Sql server SQL Server 2008 R2:带条件的游标

Sql server SQL Server 2008 R2:带条件的游标,sql-server,sql-server-2008-r2,cursor,Sql Server,Sql Server 2008 R2,Cursor,我有一个包含表id和名称的表 现在,我想通过向存储过程传递表ID来检索表名 示例: 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)

我有一个包含表id和名称的表

现在,我想通过向存储过程传递表ID来检索表名

示例

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
解释:表
表容器
包含所有表的ID和表的名称。我只想打印我已将表ID传递给存储过程的所有表名


如果我将单个值传递给变量
@TableIDs
,则该过程工作正常但是如果我将多个值(如
1,2,3
传递给
@TableIDs
),那么它就不会进入
光标

我想你不需要光标,有多种方法可以分离字符串,你可以传递
表值参数
拆分字符串
,但是按照Q要求

DECLARE@temp表(Id INT)
插入@temp值(1)、(2)、(6)
声明@TableIDs varchar(最大值),
@xml
选择@tableId='1,2,3,4,5'
选择@xml=CONVERT(xml,“+REPLACE”(@TableIDs,“,”)+”)
从@temp中选择id
我在哪里(
选择T.c.值('.',INT')
来自@xml.nodes('/root/x')T(c)
)

我认为您不需要光标,有多种方法可以分离字符串,您可以传递
表值参数
拆分字符串
,但要符合Q要求

DECLARE@temp表(Id INT)
插入@temp值(1)、(2)、(6)
声明@TableIDs varchar(最大值),
@xml
选择@tableId='1,2,3,4,5'
选择@xml=CONVERT(xml,“+REPLACE”(@TableIDs,“,”)+”)
从@temp中选择id
我在哪里(
选择T.c.值('.',INT')
来自@xml.nodes('/root/x')T(c)
)

我认为您不需要光标,有多种方法可以分离字符串,您可以传递
表值参数
拆分字符串
,但要符合Q要求

DECLARE@temp表(Id INT)
插入@temp值(1)、(2)、(6)
声明@TableIDs varchar(最大值),
@xml
选择@tableId='1,2,3,4,5'
选择@xml=CONVERT(xml,“+REPLACE”(@TableIDs,“,”)+”)
从@temp中选择id
我在哪里(
选择T.c.值('.',INT')
来自@xml.nodes('/root/x')T(c)
)

我认为您不需要光标,有多种方法可以分离字符串,您可以传递
表值参数
拆分字符串
,但要符合Q要求

DECLARE@temp表(Id INT)
插入@temp值(1)、(2)、(6)
声明@TableIDs varchar(最大值),
@xml
选择@tableId='1,2,3,4,5'
选择@xml=CONVERT(xml,“+REPLACE”(@TableIDs,“,”)+”)
从@temp中选择id
我在哪里(
选择T.c.值('.',INT')
来自@xml.nodes('/root/x')T(c)
)

您不需要将ID作为CSV列表传递。SQL Server自SQL Server 2008版本起至少已存在。TVP是一个表参数,您可以使用SQL中的普通insert语句或ADO.NET中的集合(DataTable或DataReader)向其插入数据

您可以像使用任何表或表变量一样使用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调用存储过程,可以创建一个表参数并填充它:

declare @tableIds IdTableType;

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

exec @spGetAllTables(@tableIds);

您不需要将ID作为CSV列表传递。SQL Server自SQL Server 2008版本起至少已存在。TVP是一个表参数,您可以使用SQL中的普通insert语句或ADO.NET中的集合(DataTable或DataReader)向其插入数据

您可以像使用任何表或表变量一样使用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调用存储过程,可以创建一个表参数并填充它:

declare @tableIds IdTableType;

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

exec @spGetAllTables(@tableIds);

您不需要将ID作为CSV列表传递。SQL Server自SQL Server 2008版本起至少已存在。TVP是一个表参数,您可以使用SQL中的普通insert语句或ADO.NET中的集合(DataTable或DataReader)向其插入数据

您可以像使用任何表或表变量一样使用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调用存储过程,可以创建一个表参数并填充它:

declare @tableIds IdTableType;

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

exec @spGetAllTables(@tableIds);

您不需要将ID作为CSV列表传递。SQL Server自SQL Server 2008版本起至少已存在。TVP是一个表参数,您可以使用SQL中的普通insert语句或ADO.NET中的集合(DataTable或DataReader)向其插入数据

您可以像使用任何表或表变量一样使用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调用存储过程,可以创建一个表参数并填充它:

declare @tableIds IdTableType;

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

exec @spGetAllTables(@tableIds);


您必须使用拆分函数或动态sql来处理逗号分隔的ID。这是因为变量是标量的。它们不会神奇地使您的查询作为动态sql运行。更大的问题是为什么你需要一个光标在这里?@TabAlleman,好的。我试图通过使用动态sql来解决这个问题。这看起来像是家庭作业,或者只是为了学习,因为这段代码的真实含义是完全难以捉摸的。你需要停止一行一行地思考。这里不需要光标。你只要把绳子分开就行了。下面是一篇文章,介绍了一些分割字符串的方法。更好的方法是使用单独的表,而不是存储逗号分隔的值列表。单独的表可以有索引,用于关系和查询,而CSV字段不能。在任何情况下,拆分字符串的方法都有很多,SeanLange发布的链接涵盖了所有方法。您必须使用拆分函数或动态sql来处理逗号分隔的ID