SqlServer参数化查询之where in和like实现之xml和DataTable传参
方案5 使用xml参数 对sql server xml类型参数不熟悉的童鞋需要先了解下XQuery概念,这里简单提下XQuery 是用来从 XML 文档查找和提取元素及属性的语言,简单说就是用于查询xml的语言说到这就会牵着到XPath,其实XPath是XQuery的一个子集,XQuery 1.0 和 XPath 2.0 共享相同的数据模型,并支持相同的函数和运算符,XPath的方法均适用于XQuery,假如您已经学习了 XPath,那么学习 XQuery 也不会有问题。详见//www.52php.cn/w3school/xquery/xquery_intro.htm XQuery概念了解后需要进一步了解下Sql Server对xml的支持函数,主要为query()、nodes()、exist()、value()、modify(),详见 使用xml方式实现where in时有两种实现方式,使用value和exist,在这里推荐使用exist方法,msdn是这样描述的:D.使用 exist() 方法而不使用 value() 方法 使用xml的value方法实现(不推荐) 代码如下:DataTable dt = new DataTable(); using (SqlConnection conn = new SqlConnection(connectionString)) { string xml = @" SqlCommand comm = conn.CreateCommand(); //不推荐使用value方法实现,性能相对exist要低 comm.CommandText = @"select * from Users where exists ( select 1 from @xml.nodes('/root/UserID') as T(c) where T.c.value('text()[1]','int')= Users.UserID )"; //也可以这样写,结果是一样的 //comm.CommandText = @"select * from Users // where UserID in // ( // select T.c.value('text()[1]','int') from @xml.nodes('/root/UserID') as T(c) // ) comm.Parameters.Add(new SqlParameter("@xml",SqlDbType.Xml) { Value = xml }); using (SqlDataAdapter adapter = new SqlDataAdapter(comm)) { adapter.SelectCommand = comm; adapter.Fill(dt); } } 使用xml的exist方法实现(推荐) 代码如下:DataTable dt = new DataTable(); using (SqlConnection conn = new SqlConnection(connectionString)) { string xml = @" SqlCommand comm = conn.CreateCommand(); //使用xml的exist方法实现这样能够获得较高的性能 comm.CommandText = @"select * from Users where @xml.exist('/root/UserID[text()=sql:column(""UserID"")]')=1"; comm.Parameters.Add(new SqlParameter("@xml",SqlDbType.Xml) { Value = xml }); using (SqlDataAdapter adapter = new SqlDataAdapter(comm)) { adapter.SelectCommand = comm; adapter.Fill(dt); } } 列举下不同xml结构的查询方法示例,在实际使用中经常因为不同的xml结构经常伤透了脑筋 代码如下:DataTable dt = new DataTable(); using (SqlConnection conn = new SqlConnection(connectionString)) { string xml = @" SqlCommand comm = conn.CreateCommand(); //不推荐使用value方法实现,性能相对exist要低 comm.CommandText = @"select * from Users where UserID in ( select T.c.value('UserID[1]','int') from @xml.nodes('/root/User') as T(c) )"; //也可以这样写,结果是一样的 //comm.CommandText = @"select * from Users // where exists // ( // select 1 from @xml.nodes('/root/User') as T(c) // where T.c.value('UserID[1]','int') = Users.UserID // )"; comm.Parameters.Add(new SqlParameter("@xml",SqlDbType.Xml) { Value = xml }); using (SqlDataAdapter adapter = new SqlDataAdapter(comm)) { adapter.SelectCommand = comm; adapter.Fill(dt); } } 代码如下:DataTable dt = new DataTable(); using (SqlConnection conn = new SqlConnection(connectionString)) { string xml = @" SqlCommand comm = conn.CreateCommand(); //使用xml的exist方法实现这样能够获得较高的性能 comm.CommandText = @"select * from Users where @xml.exist('/root/User[UserID=sql:column(""UserID"")]')=1"; comm.Parameters.Add(new SqlParameter("@xml",SqlDbType.Xml) { Value = xml }); using (SqlDataAdapter adapter = new SqlDataAdapter(comm)) { adapter.SelectCommand = comm; adapter.Fill(dt); } } 使用xml参数时需要注意点: 1.不同于SQL语句默认不区分大小写,xml的XQuery表达式是严格区分大小写的,所以书写时一定注意大小写问题 2.使用exist时sql:column() 中的列名须使用双引号,如sql:column("UserID"),若非要使用单引号需要连续输入两个单引号 sql:column(''UserID'') 3.不管是where in或是其他情况下使用xml查询时能用exist(看清楚了不是sql里的exists)方法就用exist方法,我们不去刻意追求性能的优化,但能顺手为之的话何乐而不为呢。 方案6 使用表值参数(Table-Valued Parameters 简称TVP Sql Server2008开始支持) 按照msdn描述TVP参数在数据量小于1000时有着很出色的性能,关于TVP可以参考 http://msdn.microsoft.com/en-us/library/bb510489.aspx 这里主要介绍如何使用TVP实现DataTable集合传参实现where in (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- tsql – SQL Server 2000:如何获取表列表和行数?
- Sqlserver与access数据库sql语法十大差异
- sql – 我们可以从函数调用存储过程吗?
- Sql Server之旅——第四站 你必须知道的非聚集索引扫描
- 如何将MS Access数据库(.mdb)文件转换为Sqlite数据库(.db)文
- SqlServer2005异常---不支持此服务器版本。目标服务器必须是
- 防SQL注入 生成参数化的通用分页查询语句
- LINQ’join’期待一个平等,但我想使用’contains’
- mysql之innodb的锁分类介绍
- sql-server – 是否可以在Microsoft SQL 2000中为表添加描述