【问题标题】:Simple dynamic TSQL query syntax简单的动态 SQL 查询语法
【发布时间】:2012-06-21 22:26:19
【问题描述】:

这可能是一个简单的答案,但我已经盯着它太久了......

我有以下查询,它将存储过程输入参数作为变量名并计算该表中的记录。我想将动态语句 (@toStartStr) 的结果检索到变量 (@toStart) 中。

-- @tempTableName = SProc input parameter
DECLARE @toStartStr nvarchar(150);
DECLARE @toStart int;
SET @toStartStr = 'SELECT @toStart = COUNT(ID) FROM ' + @tempTableName;
EXEC(@toStartStr);

现在,一个错误提示 @toStart 不能与字符串 SELECT 连接,但这是我想要的要点。谁能看到我做错了什么?或者提出替代方案?仅供参考 SQL 2008 R2。谢谢。

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008-r2 dynamic-sql


    【解决方案1】:
    DECLARE @sql NVARCHAR(255);
    
    DECLARE @toStart INT;
    
    SET @sql = N'SELECT @toStart = COUNT(ID) FROM ' + QUOTENAME(@tempTableName);
    
    EXEC sp_executesql @sql, N'@toStart INT OUTPUT', @toStart OUTPUT;
    
    PRINT @toStart;
    

    但是,如果您可以忽略当前正在进行的事务(并且您使用的是 SQL Server 2005 或更高版本 - 请在提问时指定版本!) .

    DECLARE @toStart INT;
    
    SELECT @toStart = SUM(rows) 
      FROM sys.partitions
      WHERE [object_id] = OBJECT_ID(@tempTableName)
      AND index_id IN (0,1);
    
    PRINT @toStart;
    

    为了完整起见,这里是 SQL Server 2000 的解决方案,它也不需要任何特殊权限(只需连接和公众成员):

    DECLARE @toStart INT;
    
    SELECT @toStart = [rows] 
      FROM sysindexes
      WHERE id = OBJECT_ID(@tempTableName)
      AND indid IN (0,1);
    
    PRINT @toStart;
    

    也就是说,如果您使用计数来确定下一个 ID 可能是什么,或者类似的东西,我认为您的方法是错误的,因为可以删除行并且如果它是标识列值由于回滚,可以跳过。

    【讨论】:

    • 您不一定是 sa 用户。我认为执行此查询需要管理员权限。对吗?
    • 不,我只是在我没有管理员权限的系统上进行了测试,它运行良好。
    • @Kanavi 不,查看 sys.partitions 不需要管理员权限。在告诉我删除代码之前您是否尝试过?
    • SQL 2008 R2。记录计数很好,因为这是来自文件导入的静态临时表。
    • 您的 SQL 2005+ 解决方案运行良好。我会更新问题以使其更具体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多