【问题标题】:Dynamic sql to select a specific value from a column using Joins使用连接从列中选择特定值的动态 sql
【发布时间】:2017-03-04 01:06:43
【问题描述】:

我正在尝试使用动态 sql 根据字段选择值。我有一个用于列名的字段引用表。我遇到的问题当然是动态 sql。例如,我的返回结果是(SELECT ecoa_code FROM CRA_METRO2_BASE WHERE id = 568470)。但我真的希望它运行该选择语句。执行只返回最后一行。

DECLARE @BaseCol VARCHAR(250)
SELECT 
   @BaseCol = '(SELECT ' + FR_base.field_name + ' FROM CRA_METRO2_BASE WHERE id = ' + CONVERT(VARCHAR(15), B.id) + ')'
FROM CRA_INNOVIS_AUDIT_ERROR_FIELDS E
LEFT JOIN CRA_METRO2_BASE B
    ON B.id = E.base_id
LEFT JOIN CRA_METRO2_FIELD_REF FR_base
    ON FR_base.id = E.base_field_ref
WHERE E.audit_id = @audit_id

EXEC(@BaseCol)

【问题讨论】:

  • 不能那样做。你甚至不知道它是一个有效的列名。它可以逐行更改。
  • 除非我将它加入到我的 Field_Ref 表中,该表将包含我选择的字段。立即编辑帖子。
  • 不,该表将没有该字段。该表将有一些文本(char,varchar) - 没有列的数据类型。查询优化器不能使用任何查询的输出来构建查询。
  • 是的,它会有列名的文本。有没有办法执行它产生的那一行?或者我可以采取更好的路线。
  • 你可以去 MSDN 了解动态 sql 的工作原理。现在你只是在使用这个词。

标签: tsql dynamic-sql


【解决方案1】:

如果没有模型,我不确定我是否正确理解了您的前提……;所以请对这个答案持保留态度:)

DECLARE @sqlstring VARCHAR(MAX)
SELECT @sqlstring = 'SELECT ' + a.column_name + ' FROM ' + a.[Schema] + '.' + a.table_name
from (
SELECT TOP 1 T.object_id,OBJECT_SCHEMA_NAME(T.[object_id],DB_ID()) AS [Schema],   
    T.[name] AS [table_name], AC.[name] AS [column_name]   
    --,TY.[name] AS system_data_type
    , AC.[max_length],  
    AC.[precision], AC.[scale], AC.[is_nullable], AC.[is_ansi_padded]  
    ,AC.column_id
FROM sys.tables AS T   
INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
) a
SELECT @sqlstring
EXEC(@sqlstring)

【讨论】:

    【解决方案2】:

    所以我使用了上面的查询,现在我正在使用 CTE 来构建我的基本结果列表。在我的 cte 中,我创建了更新语句,然后将它们全部放入临时表中。 我提取更新语句并在临时表上执行它们。沃拉,我有我的结果了!

    IF(OBJECT_ID('tempdb..#Temp') IS NOT NULL)
        BEGIN
            DROP TABLE #Temp
        END
    
        CREATE TABLE #Temp
        (
            usb_data VARCHAR(500), 
            cra_data VARCHAR(500)
        );
    
        WITH ErrorFieldsCTE(id, field, usb_data, cra_data, AUD, SOR, acceptable_variance, is_variance_known, is_reviewed)
        AS(
            SELECT 
                + 'UPDATE #TEMP SET usb_data = (SELECT ' + FR_base.field_name +' FROM CRA_METRO2_BASE WHERE id = '+ CONVERT(VARCHAR(25), B.id) +' ) WHERE id = ' + CONVERT(VARCHAR(15), E.id) + ' ' [usb_data],
                + 'UPDATE #TEMP SET cra_data = (SELECT ' + FR_audit.field_name +' FROM CRA_INNOVIS_INBOUND_AUDIT_INFORMATION WHERE id = '+ CONVERT(VARCHAR(25), A.id) +') WHERE id = ' + CONVERT(VARCHAR(15), E.id) + ' ' [cra_data]
            FROM CRA_INNOVIS_AUDIT_ERROR_FIELDS E
            LEFT JOIN CRA_METRO2_BASE B
                ON B.id = E.base_id
            LEFT JOIN CRA_INNOVIS_INBOUND_AUDIT_INFORMATION A
                ON A.id = E.audit_id
            LEFT JOIN CRA_METRO2_FIELD_REF FR_audit
                ON FR_audit.id = E.audit_field_ref
            LEFT JOIN CRA_METRO2_FIELD_REF FR_base
                ON FR_base.id = E.base_field_ref
            WHERE E.audit_id = @audit_id
        )
    
        INSERT INTO #Temp
        SELECT 
            id, field, usb_data, cra_data, AUD, SOR, acceptable_variance, is_variance_known, is_reviewed
        FROM ErrorFieldsCTE
    
        SELECT -- extract query
            @usb_data += usb_data + '',
            @cra_data += cra_data + '' 
        FROM #Temp
    
        EXEC(@usb_data) -- updating temp table, selects usb-data
        EXEC(@cra_data) -- updating temp table, selects cra-data
    
        SELECT  -- return to web
            id, field, usb_data, cra_data, AUD, SOR, acceptable_variance, is_variance_known, is_reviewed
        FROM #Temp
    
        IF(OBJECT_ID('tempdb..#Temp') IS NOT NULL)
        Begin
            Drop Table #Temp
        End
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多