zoukankan      html  css  js  c++  java
  • 结合C#在MSSQL中定义和使用自定义类型

          之所以会去了解这个,是因为在最近的一个项目中需要用BizTalk来处理业务数据,而每一笔业务数据又对应着表中的很多条记录,发现做BizTalk的同事在实现中,每条记录都要调用一次存储过程,而且主表数据在每一次调用时都要传入,感觉有点不太好。于是想着是不是能用table类型作为存储过程的参数。研究了一下,似乎不行。但是可以用自定义的数据类型。

          定义最普通的自定义类型很简单,见MSDN示例:     

         
    CREATE TYPE SSN
    FROM varchar(11NOT NULL ;

     

         

          详细的到帮助文档上看吧。这里主要说一下怎么把用C#定义的类引入到SQL中作为自定的数据类型。

          首先,在VS中定义一个类,这个类必须满足以下几点:

          1、添加Serializable特性以标记为是可序列化的;

          2、添加SqlUserDefinedType特性,注意设置该特性的一些属性值,如Format, Name, MaxByteSize,注意若Format设置为UserDefined的话一定要指定MaxByteSize值;

          3、实现IBinarySerialize接口,该接口中声明了Read和Write两个方法,分别是用于从BinaryReader对象中读取数据到类中的属性和把类中的属性写入到BinaryReader对象;

          4、实现INullable接口,该接口中声明了IsNull的get访问器,用于在sql中判断该类型的变量是否为null;

          5、实现静态的返回类型为当前类类型的Null只读属性,返回一个在sql中认为为null的实例;

          6、实现静态的Parse方法。该方法只有一个SqlString类型参数;

          7、重载基类的ToString方法;

          暂且只知道这一些,来看看我测试用的C#类吧:     

      

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using Microsoft.SqlServer.Server;

    namespace LfxSqlType
    {
        [Serializable]
        [SqlUserDefinedType(Format.UserDefined, Name
    ="Person", MaxByteSize=100)]
        
    public class Person : IBinarySerialize, INullable
        {
            
    public string Name;
            
    public int Age;
            
    public char Sex;

            
    #region IBinarySerialize 成员

            
    public void Read(System.IO.BinaryReader r)
            {
                
    string s = r.ReadString();
                
    string[] values = s.Split('|');
                Name 
    = values[0];
                Age 
    = Convert.ToInt32(values[1]);
                Sex 
    = Convert.ToChar(values[2]);
            }

            
    public void Write(System.IO.BinaryWriter w)
            {
                w.Write(
    string.Format("{0}|{1}|{2}", Name, Age.ToString(), Sex));
            }

            
    #endregion

            
    #region INullable 成员

            
    public bool IsNull
            {
                
    get { return string.IsNullOrEmpty(Name); }
            }

            
    #endregion

            
    public static Person Null
            {
                
    get{
                    Person p 
    = new Person();
                    p.Name 
    = string.Empty;
                    
    return p;
                }
            }

            
    public static Person Parse(SqlString str)
            {
                Person p 
    = new Person();
                
    string[] values = str.Value.Split('|');
                p.Name 
    = values[0];
                p.Age 
    = Convert.ToInt32(values[1]);
                p.Sex 
    = Convert.ToChar(values[2]);
                
    return p;
            }

            
    public override string ToString()
            {
                
    if (this.IsNull)
                    
    return "NULL";
                
    else
                    
    return string.Format("{0}|{1}|{2}", Name, Age.ToString(), Sex);
            }
        }
    }

          再来看看SQL中如何根据这个类来创建自定义类型。首先,得引用该类所在的程序集:      

    create assembly lfxtype
    from 'E:\NetSample\WinForm\SqlCustomerType\LfxSqlType\bin\Debug\LfxSqlType.dll'

          语法是create assembly sql中的程序集名 from 程序集路径。具体参见MSDN。下一步,创建具体的类型:  

    create type person
    external name lfxtype.
    [LfxSqlType.Person]

          语法跟上边的也很类似了。create type 类型名 external name sql中程序集名.[C#类完全限定名]

          接下来就可以做调用测试了:

    --创建以自定义类型为参数的存储过程
    create proc test
        
    @p person
    as
        
    print @p.Name
    go
    --定义变量
    declare @p person
    --赋值
    set @p = convert(person ,N'lfx|2|y')
    --执行存储过程
    exec test @p
    --弄个应该为null的值
    set @p = convert(person, '|2|y')
    --判断是不是真为null
    if @p is null
        
    print 'null'

         是不是很简单?呵呵

  • 相关阅读:
    简单明了的带你理解springboot原理和三大核心注解
    Spring Boot(一):入门篇
    【Mysql优化】聚簇索引与非聚簇索引概念
    Mysql索引原理与优化
    Mysql全文索引的使用
    索引的优缺点,如何创建索引
    184 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 04 例:字符串与byte(即:字节)数组间的相互转换
    183 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 03 String常用方法(下)
    182 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 02 String常用方法(上)
    181 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 01 String常用方法简介
  • 原文地址:https://www.cnblogs.com/sdlfx/p/1511296.html
Copyright © 2011-2022 走看看