使用自定义表类型(SQL Server 2008)
在 SQL Server 2008 中,用戶定義表類型是指用戶所定義的表示表結(jié)構(gòu)定義的類型。您可以使用用戶定義表類型為存儲(chǔ)過程或函數(shù)聲明表值參數(shù),或者聲明您要在批處理中或在存儲(chǔ)過程或函數(shù)的主體中使用的表變量。有關(guān)如何定義表結(jié)構(gòu)的詳細(xì)信息,請(qǐng)參閱 CREATE TABLE (Transact-SQL)。
若要?jiǎng)?chuàng)建用戶定義表類型,請(qǐng)使用 CREATE TYPE 語(yǔ)句。為了確保用戶定義表類型的數(shù)據(jù)滿足特定要求,您可以對(duì)用戶定義表類型創(chuàng)建唯一約束和主鍵。
有關(guān)與用戶定義類型相關(guān)聯(lián)的目錄視圖的信息,請(qǐng)參閱 sys.types 和 sys.table_types。
限制
?
用戶定義表類型具有下列限制:
- 用戶定義表類型不能用作表中的列或結(jié)構(gòu)化用戶定義類型中的字段。
- 基于用戶定義表類型的別名類型
- [NOT FOR REPLICATION] 選項(xiàng)是不允許的。
- CHECK 約束要求保留計(jì)算列。
- 計(jì)算列的主鍵必須是 PERSISTED 和 NOT NULL。
- 無(wú)法對(duì)用戶定義表類型創(chuàng)建非聚集索引,除非該索引是對(duì)用戶定義表類型創(chuàng)建 PRIMARY KEY 或 UNIQUE 約束的結(jié)果。(SQL Server 使用索引強(qiáng)制實(shí)施任何 UNIQUE 或 PRIMARY KEY 約束。)
- 不能在用戶定義表類型的定義中指定 DEFAULT 值。
- 在創(chuàng)建用戶定義表類型定義后不能對(duì)其進(jìn)行修改。
- 不能在用戶定義表類型的計(jì)算列的定義中調(diào)用用戶定義函數(shù)。
安全性
?
用戶定義表類型的權(quán)限通過使用下列 Transact-SQL 關(guān)鍵字來遵循 SQL Server 的對(duì)象安全模式:CREATE、GRANT、DENY、ALTER、CONTROL、TAKE OWNERSHIP、REFERENCES、EXECUTE、VIEW DEFINITION 和 REVOKE。
?
下面我用一個(gè)實(shí)例來講解一下
-- ================================
-- 創(chuàng)建和使用自定義表類型
-- 陳希章
-- ================================
USE master
GO
-- ================================
-- 創(chuàng)建測(cè)試數(shù)據(jù)庫(kù)
-- ================================
CREATE DATABASE demo
GO
-- ================================
-- 創(chuàng)建一個(gè)表
-- ================================
USE demo
GO
CREATE TABLE Customers
(
??? Id int NOT NULL,
??? Name char(10) NULL,
??? PRIMARY KEY (Id)
)
GO
USE demo
GO
-- ================================
-- 創(chuàng)建自定義表類型
-- ================================
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
-- =================================
-- 在存儲(chǔ)過程中使用自定義表類型
-- =================================
CREATE PROC GetCustomers
(@c CustomerTable READONLY)
AS
INSERT Customers SELECT * FROM @c --將傳過來的參數(shù)(其實(shí)是一個(gè)表)的數(shù)據(jù)插入到Customers表里面去
-- =================================
-- 調(diào)用該存儲(chǔ)過程,一次性插入4行數(shù)據(jù)
-- =================================
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
-- =================================
-- 清理數(shù)據(jù)庫(kù)
-- =================================
USE master
GO
DROP DATABASE demo
GO
看起來不錯(cuò)對(duì)吧,但是你應(yīng)該馬上想到一個(gè)問題,如果說這個(gè)存儲(chǔ)過程要在客戶端代碼中調(diào)用,那么該怎么提供這個(gè)參數(shù)值呢?
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);//這個(gè)類型很關(guān)鍵
??????????????? 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個(gè)客戶資料
??????? 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;
??? }
}
?
讀者可能會(huì)疑惑,這樣做實(shí)在是太棒了,可以一次性寫入100行數(shù)據(jù)呢?我們?cè)賮砜纯丛诜?wù)端到底發(fā)生了什么事情
實(shí)際上,在服務(wù)端確實(shí)會(huì)有一個(gè)定義臨時(shí)變量的過程,然后把所有的數(shù)據(jù)插入到這個(gè)變量中去,然后再執(zhí)行存儲(chǔ)過程的
最后,我們可以再深入探討探討
1. 客戶端是否一定用DataTable類型
-- 推薦使用DataTable類型,但也可以使用其他的類型,例如DataReader的數(shù)據(jù)流
2. DataTable的字段名稱是否要匹配
--不一定。只要順序一致,類型一樣就可以了。
有一個(gè)參考的blog,請(qǐng)看下面的鏈接
http://msdn.microsoft.com/zh-cn/library/bb675163.aspx
轉(zhuǎn)載于:https://www.cnblogs.com/jhxk/articles/2915476.html
總結(jié)
以上是生活随笔為你收集整理的使用自定义表类型(SQL Server 2008)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [原+转]CSS hack 小技巧 让你
- 下一篇: SQL学习笔记之存储过程的编写