【问题标题】:How to execute SQL statements saved in a table with T-SQL如何使用 T-SQL 执行保存在表中的 SQL 语句
【发布时间】:2021-01-05 10:28:06
【问题描述】:

是否可以使用 T-SQL 执行存储在表中的 SQL 语句?

DECLARE @Query text
SET @Query = (Select Query FROM SCM.dbo.CustomQuery)

存储在表中的语句是临时语句,可以是 SELECT TOP 100 * FROM ATable 到更复杂的语句:

Select
J.JobName As Job,
JD.JobDetailJobStart AS StartDate,
JD.JobDetailJobEnd AS EndDate,
(
    SELECT (DATEDIFF(dd, JD.JobDetailJobStart, JD.JobDetailJobEnd) + 1) -(DATEDIFF(wk, JD.JobDetailJobStart, JD.JobDetailJobEnd) * 2) -(CASE WHEN DATENAME(dw, JD.JobDetailJobStart) = 'Sunday' THEN -1 ELSE 0 END) -(CASE WHEN DATENAME(dw, JD.JobDetailJobEnd) = 'Saturday' THEN -1 ELSE 0 END)
) AS NumberOfWorkingDays,
JD.JobDetailDailyTarget AS DailyTarget,
JD.JobDetailWeeklyTarget AS WeeklyTarget,
JD.JobDetailRequiredQTY AS RequiredQuantity,
(
    Select SUM(sJL.JobLabourQuantityEmployees) From JobLabour sJL
) AS NumberOfEmployees,
(
    Select 
        SUM((sEM.EmployeeDesignationDefaultRate * sJL.JobLabourQuantityEmployees)*8)*(SELECT (DATEDIFF(dd, JD.JobDetailJobStart, JD.JobDetailJobEnd) + 1) -(DATEDIFF(wk, JD.JobDetailJobStart, JD.JobDetailJobEnd) * 2) -(CASE WHEN DATENAME(dw, JD.JobDetailJobStart) = 'Sunday' THEN -1 ELSE 0 END) -(CASE WHEN DATENAME(dw, JD.JobDetailJobEnd) = 'Saturday' THEN -1 ELSE 0 END))
    from EmployeeDesignation sEM
    Inner join JobLabour sJL on sJL.EmployeeDesignationID = sEM.EmployeeDesignationID
) AS FullEmployeeRate



from Job J
Inner Join JobDetail JD on JD.JobID = J.JobID
Inner Join JobLabour JL on JL.JobID = J.JobID

WHERE J.JobActive = 0

我想执行我从 T-SQL 声明的 @Query 变量。这可能吗? (我正在运行 MSSQL 2005 环境)

【问题讨论】:

  • 我不知道您的需求,但创建视图会更容易。

标签: sql sql-server tsql


【解决方案1】:

你可以使用

EXECUTE sp_executesql @Query

运行你的 T-SQL

这是 SQL Server 2005 的 MS 文档的链接

http://msdn.microsoft.com/en-us/library/ms188001%28v=sql.90%29.aspx

【讨论】:

  • 您,先生!君子学者!
  • @JacquesBronkhorst - 提示:您可以放置​​占位符,例如{CurrentUserId},在存储的查询中。当您从表中检索查询时,将每个 sn-p 替换为适当的值,例如{CurrentUserId} 可能是 42。这允许您存储返回特定用户、客户端、作业等数据的查询。
【解决方案2】:

上一个答案允许您运行一个语句,并且是有效的。问题是关于如何运行存储在一个表中的 SQL 语句,我认为它执行了多个语句。对于这个额外的步骤,涉及到一个 while 循环来遍历需要运行的每个语句。

-- Author: Chad Slagle 
DECLARE @Table table (RID BIGINT IDENTITY(1,1) PRIMARY KEY CLUSTERED, 
                        SQLText NVARCHAR(MAX) )

DECLARE  @StatementMax INT 
        ,@statementMin INT
        ,@isTest TINYINT = 1
        ,@SQLStatement NVARCHAR(MAX)
-- Insert SQL Into Temp Table
INSERT INTO @table (SQLText)
VALUES ('SELECT @@Version');
INSERT INTO @table (SQLText)
VALUES ('SELECT SERVERPROPERTY(''ProductVersion'')')
-- Get your Iterator Values
SELECT @statementMAX = MAX(RID), @statementMIN = MIN(RID)  FROM @table

IF @isTest = 1 BEGIN SELECT *, @statementMax AS MaxVal, @StatementMin AS MinVal FROM @Table END
-- Start the Loop
WHILE @StatementMax >= @statementMin
BEGIN
    SELECT @SQLStatement = SQLText FROM @table WHERE RID = @statementMin        -- Get the SQL from the table 

    IF @isTest = 1 BEGIN SELECT 'I am executing: ' + @SQLStatement AS theSqlBeingRun, GETDATE(), @statementMin, @StatementMax END  
    ELSE 
    BEGIN 
        EXECUTE sp_ExecuteSQL @SQLStatement                 -- Execute the SQL 
    END
        DELETE FROM @table WHERE RID = @statementMin        -- Delete the statement just run from the table
        SELECT @statementMIN = MIN(RID)  FROM @Table        -- Update to the next RID
    IF @isTest = 1 BEGIN  SELECT * FROM @table END

END

总之,我创建了一个临时表并将一些 SQL 放入其中,使用 IDENTITY (RID) 字段为 while 循环提供迭代器。然后运行while循环。在示例中,您应该返回 SQL 版本的两个视图。我在 2k8 上构建了这个,我希望有一天它可以帮助某人摆脱困境..

【讨论】:

    【解决方案3】:

    我们使用更简单的方法。将脚本(原始 sql 或存储过程调用)存储在一个表中,其中有一列包含所述脚本的识别代码。在脚本中使用占位符作为参数。任何经常使用的脚本都可以在您的应用程序或 Web 配置文件中“键入”。如果脚本需要按特定顺序执行,请在表中放置一个序号列。然后可以将实际的“脚本”拉入 c# 列表或数组,传递到数据库类库并相应地执行。这使您可以动态控制 SQL,并允许您在数据库端对所述脚本进行更改,而无需重新编译主应用程序。

    【讨论】:

    • 我很想知道这是否有任何缺点、安全问题或其他方面?
    【解决方案4】:
    TRUNCATE  TABLE AllTableUnion
    DECLARE @Query2 Nvarchar(MAX)
    SET @Query2='SELECT * FROM #UnionString t1)A'
    INSERT INTO AllTableUnion 
    EXEC(@Query2)
    DECLARE @Query4 Nvarchar(MAX)=(SELECT Query  FROM AllTableUnion)
    EXECUTE sp_ExecuteSQL @Query4
    

    【讨论】:

    • 您能否提供更多信息来解释您的答案,而不仅仅是一团 SQL?
    • 我有一个#unionString 表,它有一个列查询,列有一个行值查询是(从模式联合中选择*从模式1)。我将#unionstring 插入了Alltableunion。然后执行 Sp_executeSql 我得到了 Query 列的选定数据(select * from pattern union select * from pattern1)
    【解决方案5】:

    我也有类似的情况,只是无法上班。我想创建一个表格,其中有一个客户编号,以及用于确定各种项目代码的业务规则。表 psudo 如下所示:

    | CustomerNumber | RuleName       | Rule                             |
    ----------------------------------------------------------------------
    | 12345          |ShippingCharged | iif(id.ItemID in (1,2,3,4,5,6) AND 
                                        cod.Code IN (5,6,7,8),1,0)
    | 99999          |ShippingCharged | iif(id.ItemID in (1,2,3,7,9,10) AND 
                                        cod.Code NOT IN (5,7,8),1,0)
    

    我想以如下形式运行 SELECT:

    SELECT CustomerNumber, RuleName, Rule as Value
    FROM CustomerRules cr
    JOIN CustomerData cd 
         ON cd.CustomerNumber = cd.CustomerNumber
    JOIN ItemsData id 
         ON cd.ItemID = id.ItemID
    JOIN CodesData cod 
         ON cd.Code = cod.Code
    WHERE cr.RuleName = 'ShippingCharged' 
    

    返回客户编号、使用的规则名称和 IIF 语句的计算值。我得到的是规则计算的文本,而不是计算值。

    我尝试了各种形式的 DSQL 和 TSQL,但似乎无法将列视为函数,而只是表中的文本值。

    有什么想法吗?

    【讨论】:

    • 这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
    猜你喜欢
    • 2020-04-27
    • 1970-01-01
    • 2020-12-12
    • 2021-09-05
    • 2013-08-03
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多