分类: SQLServer
2013-12-20 10:05:40
说明:
本文将帮助你理解SQL Server 2008表值参数,这里已经用了ASP.NET MVC Framework 3.0,但你可以用ASP.NET MVC的其它框架。
背景:
在面向对象程序设计的开发环境中,很多情况下,我们需要存储一整列对象到数据库中,在这些情况中,程序员采用以下两个选项之一:
Microsoft SQL Server 2008能通过引入表值参数使得用户可以创建能轻易在存储程序中使用的自定义类型table的参数,来解决上述两个问题。
使用代码:
表值参数可以用如下语法来创建:
create type TVPType as table( Name nvarchar(500), Salary decimal(18,2), Age int, EndHeader bit );
在上述代码片段中,我们要注意创建自定义参数的类型和名称。在本例中,是表参数结构跟随表。一旦你执行代码,就可以在其中找到你的自定义参数。
现在我们需要创建程序来插入从应用中接收到的数据。我们将使用如下存储程序:
create proc AddDetails @tvp TVPType readonly as begin insert into TVPTable(Name, Age, Salary) select t.Name,t.Age,t.Salary from @tvp t; end
由此现在我们已经完成了数据库方面,将转向应用方面。打开一个新的MVC项目或一个你想要使用的项目。我已经使用了类型化数据集替代实体框架,因为实体框架不支持能够用于表值参数的结构化类型参数。
如下即为应用的截图(在用表值参数插入记录到数据库的前后)。
插入记录前的页面显示:
现在当我们插入记录时,我已允许用户通过使用如下JavaScript代码插入任意量的记录:
function addRow() { var table = document.getElementById('recordTable').lastChild; if (table) { var id = Number(table.children[table.children.length-1].id); if (!isNaN(id)) { id+=1; var child = document.createElement('tr'); child.id = id; var html = ''; html += ''; html += ''; child.innerHTML = html; table.appendChild(child); } } }
用户可以用“Add more”按钮添加新行,最后用“Submit”按钮提交。
我们可以通过生成一个请求,用JSON对象传送所有数据到控制器。如下即是完成上述任务的JavaScript代码:
function submitRecords() { var table = document.getElementById('recordTable').lastChild; if (table) { var childArr = table.children; if (childArr.length > 0) { var jsonArr={tvp:[]}; var nameObj, ageObj, salaryObj, id; var counter = 0; for (var i = 1; i < childArr.length; i++) { id = childArr[i].id; nameObj = document.getElementById('name_' + id); ageObj = document.getElementById('age_' + id); salaryObj = document.getElementById('salary_' + id); if (nameObj != null && nameObj.value.trim() != '' && ageObj != null && ageObj.value.trim() != '' && salaryObj != null && salaryObj.value.trim() != '') { jsonArr.tvp.push({ "name":nameObj.value.trim(), "age":ageObj.value.trim(), "salary":salaryObj.value.trim() }); } } if (jsonArr.tvp.length > 0) { $.ajax({ url: "../TVP/SubmitRecord", data:{"data":JSON.stringify(jsonArr)}, type: "POST" }); } else alert("Add data please"); } } }
在控制器一方,我们已经创建了一个函数SubmitRecord来接收我们的AJAX请求并将数据从AJAX请求中传递到相应的模型中。
[HttpPost] public ActionResult SubmitRecord(string data) { TVPModel.StoreValues(data); return View(); }
在上述代码中,HttpPost属性指定了调用函数(接收当PSOT请求时)。我们已经用NewtonSoftJson库来在模型类别上(解析JSON数据并将其存储到DataTable)解析JSON对象。
public static void StoreValues(string data) { JToken token = JObject.Parse(data); var tvp=token.SelectToken("tvp"); DataTable recordTable = Params.GetDetailsTable(); foreach (var value in tvp) { DataRow row = recordTable.NewRow(); row["Name"] = value.SelectToken("name"); row["Age"] = value.SelectToken("age"); row["Salary"] = value.SelectToken("salary"); ; row["EndHeader"] = true; recordTable.Rows.Add(row); } TVPBL bl = new TVPBL(); bl.InsertTVP(recordTable); }
创建的DataTable被作为参数传送到数据库程序。该DataTable应该和数据库端的所述类型有着同样的结构。我们已经创建了一个BL类,负责为我们的类型化数据集创建一个表适配器并调用指定的程序。
public void InsertTVP(DataTable tvpTable) { TVPTableTableAdapter adapter = GetTvpTableAdapter(); adapter.AddDetails(tvpTable); }
在完成上述程序后,我们的数据被存储在数据库中。现在当浏览主页显示“No details to show”消息时,它将不再可见。而主页将显示如下:
需要注意的点:
点击下载源代码