表值SQL Exec Query的where子句的参数

时间:2017-05-23 06:35:21

标签: sql-server

我的Exec查询中出现错误,例如“转换varchar值时转换失败”。 这是我的查询。

DECLARE @sqlText nvarchar(max); 
SET @value = 'tblLedgerNames.ledger_code, tblLedgerNames.ledger_name'; --Its a sample values,Where '@value' based on listview of the form
SET @sqlText = 'SELECT  '+@value+' ,tblSalesMaster.invoice_no,tblSalesMaster.tin_no, tblSalesMaster.entry_date
                FROM    tblLedgerNames RIGHT OUTER JOIN
                     tblSalesMaster ON tblLedgerNames.ledger_id = tblSalesMaster.account_id
    where
    sales_id <> 0'  
        + case when @Invoice_No is null then '' else ' and tblSalesMaster.invoice_no ='''+@Invoice_No+'''' end  
        + case when (select count(*) from @List_Cstmr) < 1 then '' else 
            'and tblLedgerNames.ledger_id in (' + (select * from  @List_Cstmr) + ') '  end --Where '@List_Cstmr' is an user-defined table types

    +' GROUP BY '+@value+' ,tblSalesMaster.invoice_no,tblSalesMaster.tin_no, tblSalesMaster.entry_date'
    Exec (@sqlText)

3 个答案:

答案 0 :(得分:0)

动态SQL中有许多错误。首先,这个错误:

  

转换varchar值时转换失败

可能是由@Invoice_No(我假设是数字类型)与@sqlText类型的VARCHAR连接而引起的。此外,您无法将SELECT * FROM <tbl>的结果直接连接到varchar,否则您将收到错误:

  

子查询返回的值超过1。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。

或者,如果用户定义的表只有一行,并且根据查询判断,则它是一个ledger_id列表,我认为它是数字的,这可能是上一个错误的原因。

如果你真的必须使用动态sql,你可以使用sp_executesql并传递参数:

DECLARE @sqlText NVARCHAR(MAX),
        @value NVARCHAR(MAX);

SELECT @value = 'tblLedgerNames.ledger_code, tblLedgerNames.ledger_name'; --Its a sample values,Where '@value' based on listview of the form

SELECT @sqlText = 
'SELECT
    ' + @value + ' ,tblSalesMaster.invoice_no, tblSalesMaster.tin_no, tblSalesMaster.entry_date
FROM tblLedgerNames 
RIGHT OUTER JOIN tblSalesMaster ON 
    tblLedgerNames.ledger_id = tblSalesMaster.account_id
WHERE
    sales_id <> 0' + CHAR(10)

IF @Invoice_No IS NOT NULL BEGIN
    SELECT @sqlText = @sqlText + '  AND tblSalesMaster.invoice_no = @Invoice_No' + CHAR(10)
END

IF EXISTS(SELECT 1 FROM @List_Cstmr) BEGIN
    SELECT @sqlText = @sqlText + '  AND tblLedgerNames.ledger_id IN (SELECT * FROM  @List_Cstmr)'  + CHAR(10)
END

SELECT @sqlText = @sqlText + 
'GROUP BY
' + @value + ', tblSalesMaster.invoice_no, tblSalesMaster.tin_no, tblSalesMaster.entry_date';

EXEC sp_executesql
    @sqlText,
    N'@Invoice_No INT, @List_Cstmr UserDefinedTableType READONLY',
    @Invoice_No,
    @List_Cstmr

答案 1 :(得分:0)

使用临时表的where子句中的内部选择也应该用单引号括起来。在内部选择中,您应该选择单个变量而不是*

尝试此代码:

DECLARE @sqlText nvarchar(max); 
SET @value = 'tblLedgerNames.ledger_code, tblLedgerNames.ledger_name'; --Its a sample values,Where '@value' based on listview of the form
SET @sqlText = 'SELECT  '+@value+' ,tblSalesMaster.invoice_no,tblSalesMaster.tin_no, tblSalesMaster.entry_date
                FROM    tblLedgerNames RIGHT OUTER JOIN
                     tblSalesMaster ON tblLedgerNames.ledger_id = tblSalesMaster.account_id
    where
    sales_id <> 0'  
        + case when @Invoice_No is null then '' else ' and tblSalesMaster.invoice_no ='''+@Invoice_No+'''' end  
        + case when (select count(*) from @List_Cstmr) < 1 then '' else 
            ' and tblLedgerNames.ledger_id in (select id from +' @List_Cstmr +') '  end --Where '@List_Cstmr' is an user-defined table types
    +' GROUP BY '+@value+' , tblSalesMaster.invoice_no,tblSalesMaster.tin_no, tblSalesMaster.entry_date'
    Exec (@sqlText)

答案 2 :(得分:0)

选择表类型(@List_Cstmr)到Temp表#temp,然后用Where子句中的#temp替换@List_Cstmr。 试试这个代码

DECLARE @sqlText nvarchar(max); 
SET @value = 'tblLedgerNames.ledger_code, tblLedgerNames.ledger_name'; --Its a sample values,Where '@value' based on listview of the form
SET @sqlText = 'SELECT  '+@value+' ,tblSalesMaster.invoice_no,tblSalesMaster.tin_no, tblSalesMaster.entry_date
            FROM    tblLedgerNames RIGHT OUTER JOIN
                 tblSalesMaster ON tblLedgerNames.ledger_id = tblSalesMaster.account_id
where
sales_id <> 0'  
    + case when @Invoice_No is null then '' else ' and tblSalesMaster.invoice_no ='''+@Invoice_No+'''' end  
    + case when (select count(*) from #temp) < 1 then '' else 
        ' and tblLedgerNames.ledger_id in (select id from  #temp ) '  end --Where '@List_Cstmr' is an user-defined table types
+' GROUP BY '+@value+' , tblSalesMaster.invoice_no,tblSalesMaster.tin_no, tblSalesMaster.entry_date'
Exec (@sqlText)