【问题标题】:How to store the result of dynamic SQL in a variable?如何将动态 SQL 的结果存储在变量中?
【发布时间】:2017-03-19 06:35:48
【问题描述】:

我有以下理论陈述,我想使用动态 SQL(在 SQL Server 2016 上)来实现,并将单个输出值存储在变量 (@output) 中。

@numericvar, @columnname, @tablename 应该是输入参数。任何帮助将不胜感激。非常感谢。

SELECT @output = (
    SELECT 
        MAX(CASE WHEN ROWNUM*1.0/NUMROWS <= @numericvar THEN @columnname END)
    FROM (
        SELECT
            @columnname,
            ROW_NUMBER() OVER (ORDER BY @columnname ) AS ROWNUM,
            COUNT(*) OVER (PARTITION BY NULL) AS NUMROWS
        FROM 
            @tablename 
    ) @tablename 
); 

【问题讨论】:

    标签: sql-server tsql dynamic-sql sql-server-2016 sp-executesql


    【解决方案1】:
    DECLARE @columnname SYSNAME, @tablename SYSNAME, @numericvar NUMERIC(18,2);
    DECLARE @output NUMERIC(18,2);
    
    DECLARE @sql NVARCHAR(MAX) = N'
        SET @output = (
            SELECT 
                MAX(CASE WHEN ROWNUM*1.0/NUMROWS <= @numericvar THEN '+QUOTENAME(@columnname)+N' END)
            FROM (
                SELECT
                    '+QUOTENAME(@columnname)+N',
                    ROW_NUMBER() OVER (ORDER BY '+QUOTENAME(@columnname)+N' ) AS ROWNUM,
                    COUNT(*) OVER (PARTITION BY NULL) AS NUMROWS
                FROM 
                    '+QUOTENAME(@tablename)+N'
            ) AS t
        );
    ';
    
    EXECUTE sp_executesql 
        @sql,
        N'@numericvar NUMERIC(18,2), @output NUMERIC(18,2) OUTPUT', 
        @numericvar, @output OUTPUT;
    
    SELECT @output;
    

    更新:FLOAT 输出的工作示例。该脚本使用每个人都有的INFORMATION_SCHEMA 模式中的表。

    看看你是否可以从这个示例中使它工作。如果你不能,我建议你编辑你的问题,并添加你正在使用的确切脚本 + 参数值 + 列名类型的指示。

    DECLARE @schemaname SYSNAME='INFORMATION_SCHEMA',
            @tablename  SYSNAME='COLUMNS', 
            @columnname SYSNAME='NUMERIC_PRECISION', 
            @numericvar NUMERIC(18,2)=.5;
    
    DECLARE @output_f FLOAT;
    
    DECLARE @sql NVARCHAR(MAX) = N'
        SET @output_f = (
                SELECT 
                    MAX(CASE WHEN ROWNUM*1.0/NUMROWS<=@numericvar THEN '+QUOTENAME(@columnname)+N' END)
                FROM (
                    SELECT
                        '+QUOTENAME(@columnname)+N',
                        ROW_NUMBER() OVER (ORDER BY '+QUOTENAME(@columnname)+N') AS ROWNUM,
                        COUNT(*) OVER () AS NUMROWS
                    FROM 
                        '+QUOTENAME(@schemaname)+N'.'+QUOTENAME(@tablename)+N'
                ) AS t
        );
    ';
    
    EXECUTE sp_executesql 
        @sql,
        N'@numericvar NUMERIC(18,2), @output_f FLOAT OUTPUT', 
        @numericvar, @output_f OUTPUT;
    
    SELECT @output_f;
    

    【讨论】:

    • 将 nvarchar 转换为数字数据类型时出现算术溢出错误。
    • @Kanarinox 你认为变量@output 的类型是什么?您在@columnname 中传递的列类型是什么?
    • 浮动和浮动。 (请原谅响应滞后。我是 gmt+4)。
    • @Kanarinox 更新了答案。我在想你在某处有一些 NVARCHAR() 列可能有无效的浮点值?在这种情况下,请尝试 SELECT _float_column_,TRY_CAST(_float_column_ AS FLOAT) FROM _your_table_ 来查看哪些值不是有效的浮点数。
    【解决方案2】:

    试试这个,我在这里和那里复制粘贴,你可能需要解决一下以防万一。

    declare @query nvarchar(max)
    declare @output nvarchar(max)
    declare @columnname nvarchar(max)
    declare @tablename nvarchar(max)
    declare  @numericvar NUMERIC(18,0)
    
        set @query ='SELECT @output = (
            SELECT 
                MAX(CASE WHEN ROWNUM*1.0/NUMROWS <= @numericvar THEN @columnname END)
            FROM (
                SELECT
                    @columnname,
                    ROW_NUMBER() OVER (ORDER BY @columnname ) AS ROWNUM,
                    COUNT(*) OVER (PARTITION BY NULL) AS NUMROWS
                FROM 
                    @tablename 
            ) @tablename 
        );'
    
        exec sp_executesql @query, N'@output numeric(18,2) output, 
        @columnname nvarchar(max), declare @numericvar NUMERIC(18,0),
        declare @tablename nvarchar(max)', @output= @output output, @columnname= @columnname,  @numericvar=@numericvar, @tablename=@tablename
        select @output
    

    【讨论】:

      猜你喜欢
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 2018-02-15
      • 1970-01-01
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多