\t\t在MSSQL中定義和使用C#自定義型別 SQL Server08表型別引數傳遞
在學習SQL Server 2008的過程中,突然發現SQL Server支援自定義表型別,我們可以輕鬆的將一個SQL Server 2008表型別作為引數傳遞給儲存過程。C#下實現了SQL Server 2008表型別引數傳遞
本示例中用到的型別在資料庫中的位置:
建立一個自定義表型別
CREATE TYPE [dbo].[UserDetailsType] AS TABLE
(
[ID] [varchar](50) NULL,
[Name] [varchar](50) NULL,
[Sex] [varchar](50) NULL,
[Age] [decimal](18, 0) NULL
)
建立一個名為User的表,結構如下:
建立一個儲存過程
CREATE PROCEDURE [dbo].[InsertUserInfo]
@UserInfo [UserDetailsType] readonly--指示不能在過程的主體中更新或修改引數。如果引數型別為使用者定義的表型別,則必須指定 READONLY
AS
BEGIN
insert into [User]
([ID], [Name], [Sex], [Age])
select [ID], [Name], [Sex], [Age]
from @UserInfo;
END
//啟動Visual Studio 2008,建立一個預設的窗體應用程式後,我們需要先在記憶體中建立一個數據庫表DataTable的例項,如下:
private static DataTable PrepareDatatable()
{
DataTable dt = new DataTable("dt");
DataColumn[] dtc = new DataColumn[4];
dtc[0] = new DataColumn("ID", System.Type.GetType("System.String"));
dtc[1] = new DataColumn("Name", System.Type.GetType("System.String"));
dtc[2] = new DataColumn("Sex", System.Type.GetType("System.String"));
dtc[3] = new DataColumn("Age", System.Type.GetType("System.Decimal"));
dt.Columns.AddRange(dtc);
return dt;
}
//然後,通過SqlCommand執行剛才我們建立的Test資料庫儲存過程InsertUserInfo,並傳遞我們在記憶體中建立的DataTable的例項,如下:
private static void SaveUserInfoDetails()
{
DataTable dt = PrepareDatatable();
for (int i = 0; i < = 5; i++)
{
DataRow dr = dt.NewRow();
dr[0] = i.ToString();
dr[1] = "Name" + i.ToString();
dr[2] = "男";
dr[3] = (i*10).ToString();
dt.Rows.Add(dr);
}
using (SqlConnection conn = new SqlConnection("server=Rithia;database=Test;integrated security=SSPI"))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "dbo.InsertUserInfo";
SqlParameter param = cmd.Parameters.AddWithValue("@UserInfo", dt);
conn.Open();
cmd.ExecuteNonQuery();
}
}
通過上面的示例,我們可以在程式客戶端先建立好要傳遞的表型別資料,然後傳遞給儲存過程,而儲存過程則將SQL Server 2008表型別引數中的記錄一次性的新增到了資料庫實體表中,這種操作在需要傳遞給儲存過程陣列形式的引數時非常非常方便。
--------------原始做法:---------------------------------------------
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
namespace MyDBType
{
[Serializable]//標記為是可序列化的
[SqlUserDefinedType(Format.UserDefined, Name = "Person", MaxByteSize = 100)]
/*
SqlUserDefinedType特性支援以下屬性:
Format——用語指定如何在SQL Server資料庫中序列化使用者自定義型別。其取值為Native和UserDefined;
IsByteOrdered——用於使該自定義使用者型別按其本身的位元組表示方法排序;
IsFixedLength——用於指定這個型別的所有例項是否都具有相同的長度;
MaxByteSize——用於指定該使用者自定義型別的最大位元組數;
Name——用於為使用者自定義型別指定名稱;
ValidationMethodName——用於指定校驗使用者自定義型別是否有效的方法名稱。
Format屬性最為重要,他自動使用者自定義型別如何進行序列化,選項設定為Native時是讓SQL Server資料庫自動處理所有序列化問題而不需要使用者做任何額外的操作。
但原生序列化方式只能應用到簡單類上。如果類公開了非值型別的屬性(如String),那麼該類將不能使用原生序列化。
*/
public class Person : IBinarySerialize, INullable
{
public string Name;
public int Age;
public char Sex;
/// <summary>
/// 在SQL查詢中對該屬性進行比較操作所必須指定的特性
/// </summary>
[SqlFacet(Precision = 38, Scale = 2)]
public Decimal Account;
#region IBinarySerialize 成員
/// <summary>
/// 用於從BinaryReader物件中讀取資料到類中的屬性
/// </summary>
/// <param name="r"></param>
public void Read(System.IO.BinaryReader r)
{
string s = r.ReadString();
string[] values = s.Split('|');
Name = values[0];
if (values.Length > 1) Int32.TryParse(values[1], out Age);
if (values.Length > 2) Char.TryParse(values[2], out Sex);
if (values.Length > 3) Decimal.TryParse(values[3], out Account);
}
/// <summary>
/// 把類中的屬性寫入到BinaryReader物件
/// </summary>
/// <param name="w"></param>
public void Write(System.IO.BinaryWriter w)
{
w.Write(string.Format("{0}|{1}|{2}|{3}", Name, Age.ToString(), Sex, Account));
}
#endregion
#region INullable 成員
/// <summary>
/// 用於在sql中判斷該型別的變數是否為null
/// </summary>
public bool IsNull
{
get { return string.IsNullOrEmpty(Name); }
}
#endregion
/// <summary>
/// 實現靜態的返回型別為當前類型別的Null只讀屬性,返回一個在sql中認為為null的例項
/// </summary>
public static Person Null
{
get
{
return new Person { Name = string.Empty };
}
}
/// <summary>
/// 型別轉換函式
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static Person Parse(SqlString str)
{
string[] values = str.Value.Split('|');
var p = new Person
{
Name = values[0],
};
if (values.Length > 1) Int32.TryParse(values[1], out p.Age);
if (values.Length > 2) Char.TryParse(values[2], out p.Sex);
if (values.Length > 3) Decimal.TryParse(values[3], out p.Account);
return p;
}
public override string ToString()
{
return this.IsNull ? "NULL" : string.Format("{0}|{1}|{2}|{3}", Name, Age.ToString(), Sex,Account);
}
}
}
---------SQL指令碼
select * from sys.assemblies
--引用該類所在的程式集
CREATE assembly MyType
from 'C:\MyDBType.dll'
go
--建立具體的型別 create type 型別名external name sql中程式集名.[C#類完全限定名]
CREATE TYPE person
external name MyType.[MyDBType.Person]
go
--建立以自定義型別為引數的儲存過程
create proc MyDBTypeTest
@p person
as
print @p.Name
go
--禁止在.Net Framewrok中執行使用者程式碼.啟用"clr enabled"配置選項
--在Sql Server中執行這段程式碼可以開啟CLR
exec sp_configure'show advanced options', '1';
go
reconfigure;
go
exec sp_configure'clr enabled', '1'
go
reconfigure;
exec sp_configure'show advanced options', '1';
go
--定義變數
declare @p person
--賦值Parse(SqlString str) 函式派上用場了
set @p = convert(person ,N'David.Yan|30|n|100000.99')
PRINT @p.Account
--執行儲存過程
exec MyDBTypeTest@p
--弄個應該為null的值
set @p = convert(person, '|2|y')
--判斷是不是真為null;
if @p is null
print 'bool IsNull發揮作用了,static Person Null也發揮作用了.真為null'
/*
清理現場
drop proc MyDBTypeTest
drop type person
drop assembly MyType
*/
相關推薦
\t\t在MSSQL中定義和使用C#自定義型別 SQL Server08表型別引數傳遞
在學習SQL Server 2008的過程中,突然發現SQL Server支援自定義表型別,我們可以輕鬆的將一個SQL Server 2008表型別作為引數傳遞給儲存過程。C#下實現了SQL Server 2008表型別引數傳遞本示例中用到的型別在資料庫中的位置:建立一個自定義表型別CREATE TYPE [
android:RadioButton自定義和非自定義的實現
我簡單解釋下:當root為null的時候,我們只是把一個xml檔案例項化成View物件,反回的就是xml對應的View.而當root不為null的時候,也就是存在parent.那麼我們將把這個xml例項化程View物件後,將這個View檢視add進其parent中.所以在這裡我們用的是LayoutIn
Java 知識點整理-10.Java集合框架 去除ArrayList中重複字串、自定義物件 棧和佇列 泛型 JDK5新特性 asList() toArray(T[] a) ArrayList迴圈巢狀
詳細標題:去除ArrayList中重複字串、自定義物件元素方式 棧和佇列 泛型 JDK5新特性(增強for迴圈 三種迭代(普通for、迭代器、增強for)中的元素能否刪除 靜態匯入 可變引數)Arrays工具類的asList() Collection中toArray(T[] a) 集合巢狀之Arra
C#自定義RSA加密解密及RSA簽名和驗證類實例
狀態 share normal evel thumb weight encrypt security clas 本文實例講述了C#自定義RSA加密解密及RSA簽名和驗證類。分享給大家供大家參考。具體分析如下: 這個C#類自定義RSA加密解密及RSA簽名和驗證,包含了RSA
C#自定義控制元件美化的RadionButton和CheckButton加入了Image圖示
前段時間剛在CSDN上傳了一個美化的Radionbutton和CheckButton,但是加入imagelist後,顯示不出來,在這裡我對程式碼做了一些更改,希望對大家的學習有幫助。 控制元件效果圖如下: 1. &nb
C#自定義窗體style中 button點選事件通過Command傳遞
資源字典中 < Button x:Name="BtnClose" Margin="0,-1.5,-1,0" Style="{DynamicResource ButtonClose}" HorizontalAlignment="Right" Vertic
c# 通過json.net中的JsonConverter進行自定義序列化與反序列化
iter 希望 生成 ade json.net .json implement else col 相信大家在工作中會經常遇見對json進行序列化與反序列化吧,但通常的序列化與反序列化中的json結構與c#中的類模型結構是相對應的,我們是否可以在序列化一個對象時候,讓我們
一對一視訊交友原始碼中關於圖片載入和部分自定義控制元件的原始碼
有這麼一部分原始碼,他們不如音視訊採集、播放部分的原始碼顯得那麼重要,但他們的存在使頁面看起來更美觀流暢,他們就是: 一、關於圖片載入的一段程式碼: 1、載入原圖,即沒有壓縮、裁剪、變換之前的圖,保持了原圖的大小、尺寸和解析度。 public static void displaySou
C#自定義類中操作主窗體控制元件,通過委託實現
主窗體中包含一個標籤label1和一個按鈕button1 程式碼如下: public void ChangeLabel(string text) { label1.Text = text; } private void button1_Click(o
GCC/G++編譯器和VS IDE中的一些預定義巨集和使用者自定義巨集
預定義巨集, 編譯器通常會根據平臺和編譯選項的不同,為被編譯的程式提供不同的預定義的巨集, 例如WIN32 WIN64 LINUX, 例如DEBUG, RELEASE. 1. 在使用gcc/g++編譯器時,可以通過以下命令打印出編譯器預編譯的巨集。 gcc -dM -E - < /dev/null
.net web api 中呼叫post方法和呼叫自定義方法名session使用
在開發web api的時候我們需要呼叫post方法或自定義的方法的時候,還有使用session來儲存相關的資料,首先我介紹一下如何在web api中使用session,在使用session的時候我們需要配置儲存session機制,啟用session功能,在G
C#開發學習筆記:向Dev控制元件庫中的GridControl新增自定義複選框
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">Dev控制元件庫自帶的有複選框列,預設是不顯示狀態,如果需要則設定相關
C++中關於set的自定義排序函式的書寫
大概有兩個月沒用過C++啦,手都變得很生了,在這裡,在這裡我想扯一下關於set的比較函式的定義,我想,應該有不少人對這個東西感到頭疼吧! 如果說我想在set裡面新增一個自定義的型別,比如說下面的結構體: struct Symbol { char
微信小程序-隱藏和顯示自定義的導航
傳值 hat ebs doc isp pre code nav aaa 微信小程序中不能直接操作window對象,document文檔,跟html的樹結構不相同。 實現類似導航的隱藏顯示,如圖效果: 點擊網絡顯示或隱藏網絡中包含的內容。其他類似。 如果是jquer
數據庫中的異常(預定義,非預定義,用戶自定義)
out where output 數據 sel || 非預定義異常 code err DECLARE --預定義 異常信息 不聲明異常 v_empno emp.empno%TYPE :=&empno; v_sal emp.sal%TY
C# 自定義Exception
ges 特定 ati log exce 系統 pri ado 函數 有時需要區分不同的自定義錯誤,也可能需要特定的錯誤參數,此時需要自定義一些Exception類,而方法也很簡單,簡單的說需要繼承Exception及其構造函數。 有時為了只調用特定參數,可以把其他構造函數設
在Web.config或App.config中的添加自定義配置
base .com har 信息 key 需要 lin xml文件 item .Net中的System.Configuration命名空間為我們在web.config或者app.config中自定義配置提供了完美的支持。最近看到一些項目中還在自定義xml文件做程序的配置,所
c#自定義棧
入棧 exceptio csharp 排隊 private 大小 val sta 先進後出 棧的原理是先進後出。隊列是先進先出。棧像乘坐電梯,後進的先出去。隊列就是排隊。 實現代碼: public class myStack<T> {
C#自定義處理xml數據類實例
行數 tostring 圖片 跑步 判斷 rose bool ati map 本文實例講述了C#自定義處理xml數據類。分享給大家供大家參考。具體分析如下: 這個C#類專門用戶處理xml數據,可以大大簡化xml的操作,類中封裝了常用的xml操作,包括打開、讀取xml數據,
C#自定義針對URL地址的處理類實例
new expr 操作方法 border int ignore n) spec $2 本文實例講述了C#自定義針對URL地址的處理類。分享給大家供大家參考。具體分析如下: 這個C#類是專門針對URL網址處理的類,可以對URL地址進行Base64的加密和解密,可以通過函數的