使用自定义表类型(SQL Server 2008)
在 SQL Server 2008 中,用戶定義表類型是指用戶所定義的表示表結構定義的類型。您可以使用用戶定義表類型為存儲過程或函數聲明表值參數,或者聲明您要在批處理中或在存儲過程或函數的主體中使用的表變量。有關如何定義表結構的詳細信息,請參閱 CREATE TABLE (Transact-SQL)。
若要創建用戶定義表類型,請使用 CREATE TYPE 語句。為了確保用戶定義表類型的數據滿足特定要求,您可以對用戶定義表類型創建唯一約束和主鍵。
有關與用戶定義類型相關聯的目錄視圖的信息,請參閱 sys.types 和 sys.table_types。
限制
?
用戶定義表類型具有下列限制:
- 用戶定義表類型不能用作表中的列或結構化用戶定義類型中的字段。
- 基于用戶定義表類型的別名類型
- [NOT FOR REPLICATION] 選項是不允許的。
- CHECK 約束要求保留計算列。
- 計算列的主鍵必須是 PERSISTED 和 NOT NULL。
- 無法對用戶定義表類型創建非聚集索引,除非該索引是對用戶定義表類型創建 PRIMARY KEY 或 UNIQUE 約束的結果。(SQL Server 使用索引強制實施任何 UNIQUE 或 PRIMARY KEY 約束。)
- 不能在用戶定義表類型的定義中指定 DEFAULT 值。
- 在創建用戶定義表類型定義后不能對其進行修改。
- 不能在用戶定義表類型的計算列的定義中調用用戶定義函數。
安全性
?
用戶定義表類型的權限通過使用下列 Transact-SQL 關鍵字來遵循 SQL Server 的對象安全模式:CREATE、GRANT、DENY、ALTER、CONTROL、TAKE OWNERSHIP、REFERENCES、EXECUTE、VIEW DEFINITION 和 REVOKE。
?
下面我用一個實例來講解一下
-- ================================
-- 創建和使用自定義表類型
-- 陳希章
-- ================================
USE master
GO
-- ================================
-- 創建測試數據庫
-- ================================
CREATE DATABASE demo
GO
-- ================================
-- 創建一個表
-- ================================
USE demo
GO
CREATE TABLE Customers
(
??? Id int NOT NULL,
??? Name char(10) NULL,
??? PRIMARY KEY (Id)
)
GO
USE demo
GO
-- ================================
-- 創建自定義表類型
-- ================================
CREATE TYPE dbo.CustomerTable AS TABLE
(
??? Id int NOT NULL,
??? Name char(10) NULL,
??? PRIMARY KEY (Id)
)
GO
-- =================================
-- 直接使用自定義表類型
-- =================================
DECLARE @c CustomerTable
INSERT INTO @c VALUES(1,'Xizhang')
SELECT * FROM @c
-- =================================
-- 在存儲過程中使用自定義表類型
-- =================================
CREATE PROC GetCustomers
(@c CustomerTable READONLY)
AS
INSERT Customers SELECT * FROM @c --將傳過來的參數(其實是一個表)的數據插入到Customers表里面去
-- =================================
-- 調用該存儲過程,一次性插入4行數據
-- =================================
DECLARE @temp CustomerTable
INSERT INTO @temp VALUES(7,'Xizhang')
INSERT INTO @temp VALUES(2,'Xizhang')
INSERT INTO @temp VALUES(3,'Xizhang')
INSERT INTO @temp VALUES(4,'Xizhang')
EXEC GetCustomers @c=@temp
SELECT * FROM Customers
-- =================================
-- 清理數據庫
-- =================================
USE master
GO
DROP DATABASE demo
GO
看起來不錯對吧,但是你應該馬上想到一個問題,如果說這個存儲過程要在客戶端代碼中調用,那么該怎么提供這個參數值呢?
using System.Data.SqlClient;
using System.Data;
class Program
{
??? static void Main(string[] args)
??? {
??????? DataTable tb = GetData();
??????? using (SqlConnection conn = new SqlConnection("server=sql2008;database=demo;integrated security=true"))
??????? {
??????????? using (SqlCommand cmd = conn.CreateCommand())
??????????? {
??????????????? cmd.CommandText = "GetCustomers";
??????????????? cmd.CommandType = CommandType.StoredProcedure;
??????????????? SqlParameter param = new SqlParameter("@c", SqlDbType.Structured);//這個類型很關鍵
??????????????? param.Value = tb;
??????????????? cmd.Parameters.Add(param);
??????????????? conn.Open();
??????????????? cmd.ExecuteNonQuery();
??????????????? conn.Close();
??????????? }
??????? }
??????? Console.WriteLine("完成操作");
??????? Console.Read();
??? }
??? private static DataTable GetData()
??? {
??????? DataTable tb = new DataTable();
??????? tb.Columns.Add("Id",typeof(int));
??????? tb.Columns.Add("Name", typeof(string));
??????? //添加100個客戶資料
??????? for (int i = 0; i < 100; i++)
??????? {
??????????? DataRow row = tb.NewRow();
??????????? row[0] = i;
??????????? row[1] = "Name " + i.ToString();
??????????? tb.Rows.Add(row);
??????? }
??????? return tb;
??? }
}
?
讀者可能會疑惑,這樣做實在是太棒了,可以一次性寫入100行數據呢?我們再來看看在服務端到底發生了什么事情
實際上,在服務端確實會有一個定義臨時變量的過程,然后把所有的數據插入到這個變量中去,然后再執行存儲過程的
最后,我們可以再深入探討探討
1. 客戶端是否一定用DataTable類型
-- 推薦使用DataTable類型,但也可以使用其他的類型,例如DataReader的數據流
2. DataTable的字段名稱是否要匹配
--不一定。只要順序一致,類型一樣就可以了。
有一個參考的blog,請看下面的鏈接
http://msdn.microsoft.com/zh-cn/library/bb675163.aspx
轉載于:https://www.cnblogs.com/jhxk/articles/2915476.html
總結
以上是生活随笔為你收集整理的使用自定义表类型(SQL Server 2008)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [原+转]CSS hack 小技巧 让你
- 下一篇: Drools规则引擎讲解