mssql

推荐列表 站点导航

当前位置:首页 > 数据库 > mssql >

SqlServer参数化查询之where in和like实现之xml和DataTable传参

来源:网络整理  作者:网络  发布时间:2020-12-08 20:03
在上一篇Sql Server参数化查询之where in和like实现详解中介绍了在Sql Server使用参数化查询where in的几种实现方案,遗漏了...
adapter.Fill(dt);
adapter.SelectCommand = comm;
</User>

//comm.CommandText = @"select * from Users
{
<root>
(
}

<UserID>5</UserID>

<UserID>2</UserID>
SqlCommand comm = conn.CreateCommand();
}

对sql server xml类型参数不熟悉的童鞋需要先了解下XQuery概念,这里简单提下XQuery 是用来从 XML 文档查找和提取元素及属性的语言,简单说就是用于查询xml的语言说到这就会牵着到XPath,其实XPath是XQuery的一个子集,XQuery 1.0 和 XPath 2.0 共享相同的数据模型,并支持相同的函数和运算符,XPath的方法均适用于XQuery,假如您已经学习了 XPath,那么学习 XQuery 也不会有问题。详见
}
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlConnection conn = new SqlConnection(connectionString))


adapter.Fill(dt);
<UserID>2</UserID>
adapter.SelectCommand = comm;
adapter.Fill(dt);
1.使用表值参数,首先在数据库创建表值函数
adapter.Fill(dt);

这里主要介绍如何使用TVP实现DataTable集合传参实现where in
SqlCommand comm = conn.CreateCommand();
</root>";
<User>
<UserID>1</UserID>
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))


{


{
<User>
<UserID>5</UserID>
//也可以这样写,结果是一样的
使用xml的value方法实现(不推荐)
select T.c.value('UserID[1]','int') from @xml.nodes('/root/User') as T(c)
comm.CommandText = @"select * from Users where @xml.exist('/root/User[UserID=sql:column(""UserID"")]')=1";

adapter.SelectCommand = comm;
列举下不同xml结构的查询方法示例,在实际使用中经常因为不同的xml结构经常伤透了脑筋
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))

复制代码 代码如下:

<User>
</User>
<User>
<UserID>1</UserID>
string xml = @"

使用xml方式实现where in时有两种实现方式,使用value和exist,在这里推荐使用exist方法,msdn是这样描述的:
using (SqlConnection conn = new SqlConnection(connectionString))
//comm.CommandText = @"select * from Users
<UserID>5</UserID>
{
// )

</User>

string xml = @"
// where UserID in
</User>
where T.c.value('text()[1]','int')= Users.UserID
// where exists
comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });

create type IntCollectionTVP as Table(ID int)
string xml = @"
<UserID>5</UserID>
}
{
<UserID>1</UserID>
<root>
使用xml参数时需要注意点:
由于性能原因,不在谓词中使用 value() 方法与关系值进行比较,而改用具有 sql:column() 的 exist()。
<UserID>2</UserID>

复制代码 代码如下:

using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
</root>";

复制代码 代码如下:

<root>
adapter.SelectCommand = comm;
<UserID>1</UserID>
</User>
</root>";
}


}

//使用xml的exist方法实现这样能够获得较高的性能
按照msdn描述TVP参数在数据量小于1000时有着很出色的性能,关于TVP可以参考


//也可以这样写,结果是一样的

where exists
comm.CommandText = @"select * from Users where @xml.exist('/root/UserID[text()=sql:column(""UserID"")]')=1";
D.使用 exist() 方法而不使用 value() 方法
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
  2.使用exist时sql:column() 中的列名须使用双引号,如sql:column("UserID"),若非要使用单引号需要连续输入两个单引号 sql:column(''UserID'')
XQuery概念了解后需要进一步了解下Sql Server对xml的支持函数,主要为query()、nodes()、exist()、value()、modify() ,详见

//不推荐使用value方法实现,性能相对exist要低
)";
2.表值函数创建好后进行c#调用,
where UserID in
{
// (
// select 1 from @xml.nodes('/root/User') as T(c)
{
SqlCommand comm = conn.CreateCommand();
<User>

复制代码 代码如下:

comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });
comm.CommandText = @"select * from Users

<root>
)";
注意点:

}

复制代码 代码如下:

using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
// (
// where T.c.value('UserID[1]','int') = Users.UserID

  3.不管是where in或是其他情况下使用xml查询时能用exist(看清楚了不是sql里的exists)方法就用exist方法,我们不去刻意追求性能的优化,但能顺手为之的话何乐而不为呢。
// select T.c.value('text()[1]','int') from @xml.nodes('/root/UserID') as T(c)
(

// )";

方案5 使用xml参数
</User>
string xml = @"
}


comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });
comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });

DataTable dt = new DataTable();
{
方案6 使用表值参数(Table-Valued Parameters 简称TVP Sql Server2008开始支持)
SqlCommand comm = conn.CreateCommand();
使用xml的exist方法实现(推荐)
//使用xml的exist方法实现这样能够获得较高的性能
  1.不同于SQL语句默认不区分大小写,xml的XQuery表达式是严格区分大小写的,所以书写时一定注意大小写问题
select 1 from @xml.nodes('/root/UserID') as T(c)
  3.建议定义tvp的时候最好查询条件里的类型和tvp对应字段类型保持一致,这样可以避免隐式类型转换带来的性能损失
</root>";
DataTable dt = new DataTable();
//不推荐使用value方法实现,性能相对exist要低
DataTable dt = new DataTable();
  2.构造的DataTabel列数必须和表值函数定义的一样,具体列名随意,无需和表值函数定义的列名一致,数据类型可以随意,但还是建议和表值类型定义的保持一致,一来省去隐式类型转换,二来可以在初始化DataTabel时就将不合法的参数过滤掉
comm.CommandText = @"select * from Users
<UserID>2</UserID>
<User>

  1.需要SqlParameter中的SqlDbType设置为SqlDbType.Structured然后需要设置TypeName为在数据库中创建的表值函数名,本示例中为IntCollectionTVP

相关热词:

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!

本文地址: https://v30.fanwenzhu.com/sql/mssql/1540.shtml

Copyright © www.juheyunku.com      关于 | 合作 | 声明 | 联系 | 更新 | 地图 | Tags

SqlServer参数化查询之where in和like实现之xml和DataTable传参

2020-12-08 编辑:网络

adapter.Fill(dt);
adapter.SelectCommand = comm;
</User>

//comm.CommandText = @"select * from Users
{
<root>
(
}

<UserID>5</UserID>

<UserID>2</UserID>
SqlCommand comm = conn.CreateCommand();
}

对sql server xml类型参数不熟悉的童鞋需要先了解下XQuery概念,这里简单提下XQuery 是用来从 XML 文档查找和提取元素及属性的语言,简单说就是用于查询xml的语言说到这就会牵着到XPath,其实XPath是XQuery的一个子集,XQuery 1.0 和 XPath 2.0 共享相同的数据模型,并支持相同的函数和运算符,XPath的方法均适用于XQuery,假如您已经学习了 XPath,那么学习 XQuery 也不会有问题。详见
}
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlConnection conn = new SqlConnection(connectionString))


adapter.Fill(dt);
<UserID>2</UserID>
adapter.SelectCommand = comm;
adapter.Fill(dt);
1.使用表值参数,首先在数据库创建表值函数
adapter.Fill(dt);

这里主要介绍如何使用TVP实现DataTable集合传参实现where in
SqlCommand comm = conn.CreateCommand();
</root>";
<User>
<UserID>1</UserID>
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))


{


{
<User>
<UserID>5</UserID>
//也可以这样写,结果是一样的
使用xml的value方法实现(不推荐)
select T.c.value('UserID[1]','int') from @xml.nodes('/root/User') as T(c)
comm.CommandText = @"select * from Users where @xml.exist('/root/User[UserID=sql:column(""UserID"")]')=1";

adapter.SelectCommand = comm;
列举下不同xml结构的查询方法示例,在实际使用中经常因为不同的xml结构经常伤透了脑筋
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))

复制代码 代码如下:

<User>
</User>
<User>
<UserID>1</UserID>
string xml = @"

使用xml方式实现where in时有两种实现方式,使用value和exist,在这里推荐使用exist方法,msdn是这样描述的:
using (SqlConnection conn = new SqlConnection(connectionString))
//comm.CommandText = @"select * from Users
<UserID>5</UserID>
{
// )

</User>

string xml = @"
// where UserID in
</User>
where T.c.value('text()[1]','int')= Users.UserID
// where exists
comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });

create type IntCollectionTVP as Table(ID int)
string xml = @"
<UserID>5</UserID>
}
{
<UserID>1</UserID>
<root>
使用xml参数时需要注意点:
由于性能原因,不在谓词中使用 value() 方法与关系值进行比较,而改用具有 sql:column() 的 exist()。
<UserID>2</UserID>

复制代码 代码如下:

using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
</root>";

复制代码 代码如下:

<root>
adapter.SelectCommand = comm;
<UserID>1</UserID>
</User>
</root>";
}


}

//使用xml的exist方法实现这样能够获得较高的性能
按照msdn描述TVP参数在数据量小于1000时有着很出色的性能,关于TVP可以参考


//也可以这样写,结果是一样的

where exists
comm.CommandText = @"select * from Users where @xml.exist('/root/UserID[text()=sql:column(""UserID"")]')=1";
D.使用 exist() 方法而不使用 value() 方法
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
  2.使用exist时sql:column() 中的列名须使用双引号,如sql:column("UserID"),若非要使用单引号需要连续输入两个单引号 sql:column(''UserID'')
XQuery概念了解后需要进一步了解下Sql Server对xml的支持函数,主要为query()、nodes()、exist()、value()、modify() ,详见

//不推荐使用value方法实现,性能相对exist要低
)";
2.表值函数创建好后进行c#调用,
where UserID in
{
// (
// select 1 from @xml.nodes('/root/User') as T(c)
{
SqlCommand comm = conn.CreateCommand();
<User>

复制代码 代码如下:

comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });
comm.CommandText = @"select * from Users

<root>
)";
注意点:

}

复制代码 代码如下:

using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
// (
// where T.c.value('UserID[1]','int') = Users.UserID

  3.不管是where in或是其他情况下使用xml查询时能用exist(看清楚了不是sql里的exists)方法就用exist方法,我们不去刻意追求性能的优化,但能顺手为之的话何乐而不为呢。
// select T.c.value('text()[1]','int') from @xml.nodes('/root/UserID') as T(c)
(

// )";

方案5 使用xml参数
</User>
string xml = @"
}


comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });
comm.Parameters.Add(new SqlParameter("@xml", SqlDbType.Xml) { Value = xml });

DataTable dt = new DataTable();
{
方案6 使用表值参数(Table-Valued Parameters 简称TVP Sql Server2008开始支持)
SqlCommand comm = conn.CreateCommand();
使用xml的exist方法实现(推荐)
//使用xml的exist方法实现这样能够获得较高的性能
  1.不同于SQL语句默认不区分大小写,xml的XQuery表达式是严格区分大小写的,所以书写时一定注意大小写问题
select 1 from @xml.nodes('/root/UserID') as T(c)
  3.建议定义tvp的时候最好查询条件里的类型和tvp对应字段类型保持一致,这样可以避免隐式类型转换带来的性能损失
</root>";
DataTable dt = new DataTable();
//不推荐使用value方法实现,性能相对exist要低
DataTable dt = new DataTable();
  2.构造的DataTabel列数必须和表值函数定义的一样,具体列名随意,无需和表值函数定义的列名一致,数据类型可以随意,但还是建议和表值类型定义的保持一致,一来省去隐式类型转换,二来可以在初始化DataTabel时就将不合法的参数过滤掉
comm.CommandText = @"select * from Users
<UserID>2</UserID>
<User>

  1.需要SqlParameter中的SqlDbType设置为SqlDbType.Structured然后需要设置TypeName为在数据库中创建的表值函数名,本示例中为IntCollectionTVP

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供学习参考!
本文地址为 https://v30.fanwenzhu.com/sql/mssql/1540.shtml

相关文章

风云图片

推荐阅读

返回mssql频道首页