2

我正在使用 SQL Server 2008 RC2。

我们经常不得不做一个类似这样的查询:

select * from Site s where s.name in (:names)

":names"1000 个逗号StringBuilder分隔的 18 字节名称在哪里。这需要一段时间才能运行;在我的本地开发机器上最多一分钟。我知道很多人Table Valued Parameters为此建议使用(TVP),例如下面的示例:

create procedure [dbo].[sp_TestSites] @siteNames SiteNameTableType readonly
as
begin
    select s.* from Site s
       inner join @siteNames d on d.name = s.name
end

但是由于 Microsoft JDBC Driver 仍然不支持 TVP(据我所知),实现这一目标的最佳方法是什么?将一长串逗号分隔值发送到存储过程,然后在过程中拆分字符串并插入临时表?例子:

create type dbo.SiteNameTableType as table(
    name varchar(18) not null unique
)

create procedure sp_TestSites(
    @longStringOfNames varchar(max))
as
begin
    declare @siteNames SiteNameTableType

    insert into @siteNames
    select * from dbo.split(@longStringOfNames) -- assume I have a Split function

    select s.* from Site s
       inner join @siteNames d on d.name = s.name
end
4

2 回答 2

1

正如我在评论中提到的,您可以将数据准备为 XML 字符串并将其传递给存储过程。在 SP 中,您可以查询该 XML 并根据需要加入结果集。

于 2013-05-28T13:38:41.757 回答
1

您还可以将 CSV 字符串传递给您的 SP,在 SP 中使用 FUNCTION 将 CSV 字符串转换为 TVP,然后使用它?

例子:

CREATE FUNCTION [dbo].[GET_TABLE_FROM_CSVSTRING] ( @CSVString VARCHAR(MAX))
RETURNS  @Result TABLE(ItemValue VARCHAR(MAX)) 
AS
BEGIN

    DECLARE @x XML 
    SELECT @x = CAST('<A>'+ REPLACE(@CSVString,',','</A><A>')+ '</A>' AS XML)

    INSERT INTO @Result            
    SELECT t.value('.', 'VARCHAR(MAX)') AS inVal
    FROM @x.nodes('/A') AS x(t)

    RETURN
END   
GO

我不知道这是否是最快的字符串拆分器,但我会检查一下。注意:为了在您的特定情况下获得更好的性能,请修改生成的 TVP 定义(和 XML 代码)以包含您期望的 Exact Column 域(以帮助查询优化器)。即,如果您确定单个值的长度最大为 50 个字符,则不要使用 VARCHAR(MAX) 而使用 VARCHAR(50)。

于 2015-06-26T07:58:31.807 回答