【问题标题】:SQL using a variable SQL query within another variable SQL query在另一个变量 SQL 查询中使用变量 SQL 查询的 SQL
【发布时间】:2020-04-30 07:32:07
【问题描述】:

我创建了一个变量 SQL 查询,我在其中声明了我想要使用的 SQL 查询,因为变量表名称。我们的 SQL 是根据系统中的帐户名设置的。这意味着它看起来有点像这样:[LSRetail].[dbo].[AccountName$Item]

这里的LSRetail 部分是动态的,因为如果它是丹麦,它被称为LSRetailDK,如果它是瑞典,它被称为LSRetailSEAccountName 也是动态的,因为商店名称和邮政编码不同...

所有这些实际上都有效并且被声明并设置为@Sql,但是由于空间的原因,我想做另一个DECLARE @Sql2 VARCHAR(8000),我想在其中SELECT * FROM @Sql。由于@Sqlwith cte1 AS ( 语句开头,它不允许我这样做。

这里可以做点什么吗?我想将两者结合在@Sql2@Sql3 中。 现在,唯一有效的是 SET @Sql2 = @Sql 并执行它。

下面的代码是@Sql 的代码,我想在@Sql2 中使用它。

DECLARE @OrderNo VARCHAR(50);
DECLARE @StoreName VARCHAR(100);
DECLARE @Table1 VARCHAR(1000);
DECLARE @Table2 VARCHAR(1000);
DECLARE @Table3 VARCHAR(1000);
DECLARE @Table4 VARCHAR(1000);
DECLARE @Table5 VARCHAR(1000);
DECLARE @Table6 VARCHAR(1000);
DECLARE @Table7 VARCHAR(1000);
DECLARE @Table8 VARCHAR(1000);
DECLARE @Table9 VARCHAR(1000);
DECLARE @Database VARCHAR(1000);
DECLARE @BulkDiscount VARCHAR(1000);
DECLARE @DisclaimerDiscount VARCHAR(1000);
DECLARE @CashDiscount VARCHAR(1000);
DECLARE @Loyalty VARCHAR(1000);
DECLARE @Orders VARCHAR(8000);


SET @Database = '[LSRetail]'
SET @StoreName = 'AccountName';
SET @Orders = '''TI0573057'', ''TI0572704'', ''TI0572541'', ''TI0573058'', ''TI0572983'', ''TI0572595'', ''TI0573516'', ''TI0572841'', ''TI0573175'', ''TI0572759'', ''TI0572861'', ''TI0572917'', ''TI0568408'', ''TI0573077'', ''TI0572641'', ''TI0570757'', ''TI0573419'', ''TI0573394'', ''TI0572893'', ''TI0573029'', ''TI0573317'', ''TI0572581'', ''TI0570652'', ''TI0573061'', ''TI0573340'', ''TI0572417'', ''TI0572769'', ''TI0573315'', ''TI0572975'', ''TI0573304'', ''TI0573381'', ''TI0572976'', ''TI0572862'', ''TI0572886'', ''TI0573615'', ''TI0573049'', ''TI0572811'', ''TI0573156'', ''TI0573222'', ''TI0573095'', ''TI0573023''';

SET @BulkDiscount = 2.5/100
SET @DisclaimerDiscount = 1.5/100
SET @CashDiscount = 0.0/100
SET @Loyalty = 5.3/100

SET @Table1 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Invoice Line]');
SET @Table2 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Invoice Header]');
SET @Table3 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Item]');
SET @Table4 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Cr_Memo Line]');
SET @Table5 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Cr_Memo Header]');
SET @Table6 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Inv_ Header]');
SET @Table7 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Inv_ Line]');
SET @Table8 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Cr_ Memo Hdr_]');
SET @Table9 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Cr_ Memo Line]');

DECLARE @Sql VARCHAR(8000);
SET @Sql =
'
WITH cte1 AS(
SELECT a.[Document No_]
      ,''Invoice'' AS [Document Type]
      ,b.[Unique Document No_]
      ,a.[Type]
      ,a.[No_]
      ,c.[Vendor Item No_]
      ,a.[Gen_ Prod_ Posting Group]
      ,a.[VAT Bus_ Posting Group]
      ,a.[VAT Prod_ Posting Group]
      ,a.[Description]
      ,a.[Item Order Group Code]
      ,a.[Quantity]
      ,a.[Unit of Measure]
      ,a.[Unit Cost (LCY)]
      ,a.[Unit Price]
      ,a.[Line Amount]
      ,a.[Line Discount %]
      ,a.[Line Amount]/(a.[VAT %]/100+1)*0.96 AS [Total Line Sales]
      ,CASE WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @DisclaimerDiscount + ') * (1-' + @BulkDiscount + ') * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] LIKE ''SM%'' OR a.[No_] LIKE ''LE%'' AND a.[No_] LIKE ''%99999''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] <> ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] = ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
       END AS [Total Line Cost]
FROM ' + @Table1 + ' a
LEFT JOIN ' + @Table2 + ' b ON a.[Document No_] = b.[No_]
LEFT JOIN ' + @Table3 + ' c ON a.[No_] = c.[No_]
WHERE b.[Prepayment Invoice] = 0
),
cte2 AS(
SELECT a.[Document No_]
      ,''Credit Memo'' AS [Document Type]
      ,b.[Unique Document No_]
      ,a.[Type]
      ,a.[No_]
      ,c.[Vendor Item No_]
      ,a.[Gen_ Prod_ Posting Group]
      ,a.[VAT Bus_ Posting Group]
      ,a.[VAT Prod_ Posting Group]
      ,a.[Description]
      ,a.[Item Order Group Code]
      ,a.[Quantity] * (-1) AS [Quantity]
      ,a.[Unit of Measure]
      ,a.[Unit Cost (LCY)]
      ,a.[Unit Price]
      ,a.[Line Amount]
      ,a.[Line Discount %]
      ,a.[Line Amount]/(a.[VAT %]/100+1)*0.96 AS [Total Line Sales]
      ,CASE WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @DisclaimerDiscount + ') * (1-' + @BulkDiscount + ') * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] LIKE ''SM%'' OR a.[No_] LIKE ''LE%'' AND a.[No_] LIKE ''%99999''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] <> ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] = ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
       END AS [Total Line Cost]
FROM ' + @Table4 + ' a
LEFT JOIN ' + @Table5 + ' b ON a.[Document No_] = b.[No_]
LEFT JOIN ' + @Table3 + ' c ON a.[No_] = c.[No_]
WHERE b.[Prepayment Credit Memo] = 0
),
cte3 AS(
SELECT *
FROM cte1
UNION ALL
SELECT *
FROM cte2
)
SELECT *
      ,CASE WHEN [Total Line Sales] <> 0
            THEN ([Total Line Sales] - [Total Line Cost])
            ELSE 0
       END AS [Margin]
      ,CASE WHEN [Total Line Sales] <> 0
            THEN ([Total Line Sales] - [Total Line Cost])/[Total Line Sales]
            ELSE 0
       END AS [Margin %]
FROM cte3
WHERE [No_] <> ''''
AND [Unique Document No_] IN (' + @Orders + ')
ORDER BY [Unique Document No_], [Item Order Group Code]
'

提前感谢您的帮助。

注意:我使用 SQL Server。

【问题讨论】:

  • 为什么不粘贴示例代码和预期的输出。我认为这比您的文字容易理解。
  • @JaimeDrq 现在已添加到其中 - 这是一个很长的代码 :)
  • 这感觉就像您需要修复您的设计,而不是 SQL。每个商店都有不同的桌子是你遇到问题的原因。修复设计,修复问题。
  • 旁注:[','' + @StoreName + '','$Sales Invoice Line] 这样的代码不是注入证明。像'MyTable]; DROP TABLE dbo.MyTable];-- 这样的值仍然会注入。如果必须注入对象名称,请使用QUOTENAME切勿将未经处理的字符串注入您的动态查询中。
  • 你也必须参数化你的陈述(我不能强调必须更多) . ' + @DisclaimerDiscount + ' 是一个非常的坏主意。评论不是告诉你如何正确编码的地方,没有巨大的安全漏洞,所以请花时间阅读我在Dos and Don'ts of Dynamic SQL写的一篇文章

标签: sql-server tsql dynamic-sql


【解决方案1】:

我找到了解决问题的方法...

通过删除最后一个 SELECT 语句,我能够在第二个变量中使用它。

DECLARE @OrderNo VARCHAR(50);
DECLARE @StoreName VARCHAR(100);
DECLARE @Table1 VARCHAR(1000);
DECLARE @Table2 VARCHAR(1000);
DECLARE @Table3 VARCHAR(1000);
DECLARE @Table4 VARCHAR(1000);
DECLARE @Table5 VARCHAR(1000);
DECLARE @Table6 VARCHAR(1000);
DECLARE @Table7 VARCHAR(1000);
DECLARE @Table8 VARCHAR(1000);
DECLARE @Table9 VARCHAR(1000);
DECLARE @Database VARCHAR(1000);
DECLARE @BulkDiscount VARCHAR(1000);
DECLARE @DisclaimerDiscount VARCHAR(1000);
DECLARE @CashDiscount VARCHAR(1000);
DECLARE @Loyalty VARCHAR(1000);
DECLARE @Orders VARCHAR(8000);


SET @Database = '[LSRetail]'
SET @StoreName = 'AccountName';
SET @Orders = '''TI0573057'', ''TI0572704'', ''TI0572541'', ''TI0573058'', ''TI0572983'', ''TI0572595'', ''TI0573516'', ''TI0572841'', ''TI0573175'', ''TI0572759'', ''TI0572861'', ''TI0572917'', ''TI0568408'', ''TI0573077'', ''TI0572641'', ''TI0570757'', ''TI0573419'', ''TI0573394'', ''TI0572893'', ''TI0573029'', ''TI0573317'', ''TI0572581'', ''TI0570652'', ''TI0573061'', ''TI0573340'', ''TI0572417'', ''TI0572769'', ''TI0573315'', ''TI0572975'', ''TI0573304'', ''TI0573381'', ''TI0572976'', ''TI0572862'', ''TI0572886'', ''TI0573615'', ''TI0573049'', ''TI0572811'', ''TI0573156'', ''TI0573222'', ''TI0573095'', ''TI0573023''';

SET @BulkDiscount = 2.5/100
SET @DisclaimerDiscount = 1.5/100
SET @CashDiscount = 0.0/100
SET @Loyalty = 5.3/100

SET @Table1 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Invoice Line]');
SET @Table2 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Invoice Header]');
SET @Table3 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Item]');
SET @Table4 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Cr_Memo Line]');
SET @Table5 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Sales Cr_Memo Header]');
SET @Table6 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Inv_ Header]');
SET @Table7 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Inv_ Line]');
SET @Table8 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Cr_ Memo Hdr_]');
SET @Table9 = CONCAT(@Database,'.[dbo].[','' + @StoreName + '','$Purchase Cr_ Memo Line]');

DECLARE @Sql VARCHAR(8000);
SET @Sql =
'
WITH cte1 AS(
SELECT a.[Document No_]
      ,''Invoice'' AS [Document Type]
      ,b.[Unique Document No_]
      ,a.[Type]
      ,a.[No_]
      ,c.[Vendor Item No_]
      ,a.[Gen_ Prod_ Posting Group]
      ,a.[VAT Bus_ Posting Group]
      ,a.[VAT Prod_ Posting Group]
      ,a.[Description]
      ,a.[Item Order Group Code]
      ,a.[Quantity]
      ,a.[Unit of Measure]
      ,a.[Unit Cost (LCY)]
      ,a.[Unit Price]
      ,a.[Line Amount]
      ,a.[Line Discount %]
      ,a.[Line Amount]/(a.[VAT %]/100+1)*0.96 AS [Total Line Sales]
      ,CASE WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @DisclaimerDiscount + ') * (1-' + @BulkDiscount + ') * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] LIKE ''SM%'' OR a.[No_] LIKE ''LE%'' AND a.[No_] LIKE ''%99999''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] <> ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] = ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
       END AS [Total Line Cost]
FROM ' + @Table1 + ' a
LEFT JOIN ' + @Table2 + ' b ON a.[Document No_] = b.[No_]
LEFT JOIN ' + @Table3 + ' c ON a.[No_] = c.[No_]
WHERE b.[Prepayment Invoice] = 0
),
cte2 AS(
SELECT a.[Document No_]
      ,''Credit Memo'' AS [Document Type]
      ,b.[Unique Document No_]
      ,a.[Type]
      ,a.[No_]
      ,c.[Vendor Item No_]
      ,a.[Gen_ Prod_ Posting Group]
      ,a.[VAT Bus_ Posting Group]
      ,a.[VAT Prod_ Posting Group]
      ,a.[Description]
      ,a.[Item Order Group Code]
      ,a.[Quantity] * (-1) AS [Quantity]
      ,a.[Unit of Measure]
      ,a.[Unit Cost (LCY)]
      ,a.[Unit Price]
      ,a.[Line Amount]
      ,a.[Line Discount %]
      ,a.[Line Amount]/(a.[VAT %]/100+1)*0.96 AS [Total Line Sales]
      ,CASE WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @DisclaimerDiscount + ') * (1-' + @BulkDiscount + ') * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] LIKE ''SM%'' OR a.[No_] LIKE ''LE%'' AND a.[No_] LIKE ''%99999''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] <> ''OVT00100'' AND a.[Item Order Group Code] <> ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity] * (1-' + @CashDiscount + ') * (1-' + @Loyalty + ')
            WHEN a.[No_] NOT LIKE ''SM%'' OR a.[No_] NOT LIKE ''LE%'' AND a.[No_] NOT LIKE ''%99999'' AND a.[Item Order Group Code] = ''OVT00100'' AND a.[Item Order Group Code] = ''OVT00500''
            THEN a.[Unit Cost (LCY)]*a.[Quantity]
       END AS [Total Line Cost]
FROM ' + @Table4 + ' a
LEFT JOIN ' + @Table5 + ' b ON a.[Document No_] = b.[No_]
LEFT JOIN ' + @Table3 + ' c ON a.[No_] = c.[No_]
WHERE b.[Prepayment Credit Memo] = 0
),
cte3 AS(
SELECT *
FROM cte1
UNION ALL
SELECT *
FROM cte2
)
'
@DECLARE @Sql2 VARCHAR(8000);
SET @Sql2 =
@Sql + '
SELECT *
      ,CASE WHEN [Total Line Sales] <> 0
            THEN ([Total Line Sales] - [Total Line Cost])
            ELSE 0
       END AS [Margin]
      ,CASE WHEN [Total Line Sales] <> 0
            THEN ([Total Line Sales] - [Total Line Cost])/[Total Line Sales]
            ELSE 0
       END AS [Margin %]
FROM cte3
WHERE [No_] <> ''''
AND [Unique Document No_] IN (' + @Orders + ')
ORDER BY [Unique Document No_], [Item Order Group Code]
'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多