SQL Server 2008 R2:有条件的游标

SQL Server 2008 R2: Cursor with condition

我有 table,其中包含 table 的 ID 和名称。

现在我想通过将 table ID 传递给存储过程来检索 table 名称。

示例

create procedure spGetAllTables
@TableIDs varchar(max)

AS

DECLARE @Tables varchar(max)

    DECLARE Cur1 CURSOR FAST_FORWARD FOR
    SELECT TableName FROM TablesContainer
    WHERE TableID IN (@TableIDs)

    OPEN Cur1
    FETCH NEXT FROM Cur1 INTO @Tables
    WHILE(@@FETCH_STATUS=0)
    BEGIN
        PRINT(@Tables)
        FETCH NEXT FROM Cur1 INTO @Tables

    END

    CLOSE Cur1;

    DEALLOCATE Cur1;

GO

说明:table TablesContainer包含所有table的ID和table的名字。我只想打印我已将其 table ID 传递给存储过程的所有 table 名称。

如果我将单个值传递给变量 @TableIDs,则该过程工作正常。 但是 如果我将 1,2,3 之类的多个值传递给 @TableIDs 那么它就不会进入 cursor.

我认为你不需要游标,有多种方法可以分隔字符串,你可以传递 table value parametersplit the string 但根据 Q 要求 Reference

DECLARE @temp TABLE (Id INT)
INSERT INTO @temp VALUES (1),(2),(6)

DECLARE @TableIDs  varchar(max),
        @xml xml

SELECT @TableIDs = '1,2,3,4,5'
SELECT @xml = CONVERT(xml,' <root> <x>' + REPLACE(@TableIDs,',','</x> <x>') + '</x>   </root> ')


SELECT id FROM @temp
WHERE id IN (
SELECT  T.c.value('.','INT')
        FROM @xml.nodes('/root/x') T(c)     
)

您不需要将 ID 作为 CSV 列表传递。 SQL 服务器自 SQL Server 2008 版本起至少有 table-valued parameters。 TVP 是一个 table 参数,您可以在 SQL 中使用纯 INSERT 语句向其插入数据,或者在 ADO.NET 中作为集合(DataTable 或 DataReader)插入数据。

您可以像使用任何 table 或 table 变量一样使用 TVP 加入。

首先需要在数据库中定义TVP类型:

CREATE TYPE IdTableType AS TABLE ( ID uniqueidentifier);

那你可以写一个存储过程来使用它:

create procedure spGetAllTables(@TableIDs IdTableType READONLY)
AS
    SELECT TableName 
    FROM TablesContainer
    inner join @TableIDs on @TableIDs.ID=TablesContainer.TableID

要从 T-SQL 调用存储过程,您可以创建一个 table 参数并填充它:

declare @tableIds IdTableType;

insert into @tableIds 
VALUES
('....'),
('....');

exec @spGetAllTables(@tableIds);