我的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)
答案 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)