【问题标题】:Converting T-SQL to MySQL with temp tables使用临时表将 T-SQL 转换为 MySQL
【发布时间】:2020-11-18 09:05:01
【问题描述】:

我正在将 T-SQL 存储过程转换为 MySQL。我不熟悉 T-SQL,并且正在努力变得更加熟悉临时表和存储过程。提前感谢您的帮助。

T-SQL 原始文件如下所示(编辑: 注意这只是用于生成报告的原始过程的一部分):

DROP TABLE IF EXISTS #accounts;

SELECT  d.data_id                   
        ,p.pp_name AS name
        ,CONVERT(tinyint,1) AS flag             
        ,d.pd_date
        ,CONVERT(char(6),pd_date,112) AS date_period                
        ,CONVERT(varchar(3),0) AS n_phones                          
INTO    #accounts                   
from    table_detail d                  
    JOIN    table_pool p ON d.pp_id = p.pp_id                   
    JOIN    table_type t ON p.pp_type_id = t.pp_type_id                                                     
    JOIN    Inventory i ON d.data_id = i.data_id                    
    JOIN    Product pr ON i.product_id = pr.product_id  
WHERE   pp_name IN (SELECT name FROM Sandbox..desired_sandbox)                  
    AND DATEDIFF(MONTH,pd_date,GETDATE()) < 3
            
                        
UPDATE  a                   
SET     a.flag = 0              
FROM    #accounts a                 
JOIN    table_detail d ON a.data_id = d.data_id                 
JOIN    table_pool p ON d.pp_id = p.pp_id                   
WHERE   d.pd_date < a.pd_date                   
    AND pp_name != 'error';     

我当前的更新如下。我是否需要将其包装在 CREATE TEMPORARY TABLE IF NOT EXISTS accounts AS (&lt;insert query here&gt;) 而不是 INTO #accounts 中?

SELECT  d.data_id                   
        ,p.pp_name AS name                              
        ,CONVERT(tinyint,1) AS flag             
        ,d.pd_date
        ,DATE_FORMAT(pd_date,'%Y%m%d') AS date_period               
        ,CONVERT(varchar(3),0) AS n_phones                                  
FROM    table_detail d                  
    JOIN    table_pool p ON d.pp_id = p.pp_id                   
    JOIN    table_type t ON p.pp_type_id = t.pp_type_id                                 
    JOIN    Inventory i ON d.data_id = i.data_id                    
    JOIN    Product pr ON i.product_id = pr.product_id  
WHERE   pp_name IN (SELECT name FROM Sandbox..desired_sandbox)              
    AND TIMESTAMPDIFF(MONTH,pd_date,NOW()) < 3

假设语法正确,然后执行以下操作:

UPDATE  accounts a -- Is this the correct way to add an alias and update the temp table?                
    JOIN    table_detail d ON a.data_id = d.data_id                 
    JOIN    table_pool p ON d.pp_id = p.pp_id                   
SET     a.flag = 0              
WHERE   d.pd_date < a.pd_date                   
    AND pp_name != 'error'; 

最后,我假设我可以按照this post 将最终查询包装到存储过程中,对吗?总结一下帖子中的代码:

drop procedure if exists procedure_name;
DELIMITER $$
create procedure procedure_name ()
BEGIN
    DROP TEMPORARY TABLE IF EXISTS accounts;

    CREATE TEMPORARY TABLE accounts AS (
    SELECT...
    FROM...
    WHERE...
    ;
    )

    UPDATE accounts
        JOIN ...
        JOIN ...
    SET...
    WHERE...;
    
    DROP TEMPORARY TABLE accounts; -- otherwise it survives the stored proc call
END
$$ -- signify end of block
DELIMITER ; -- reset to default delimiter

【问题讨论】:

  • 您使用的是 mysql 8.x 吗?那么你可以使用 WITH 子句,你发布的存储过程也很好,适合你的目的
  • 谢谢,我将不得不努力从 DBA 获取版本,但我认为不会。感谢您的指导,但很高兴听到我在正确的轨道上。
  • 这个过程的意义何在?更新一个临时表并且以后不对它做其他事情没有多大意义。
  • 我是用它来做报表的,所以最后有一个查询。我想将我不确定的部分所需的代码量保持在最低限度。我应该在一开始就提到这一点。

标签: mysql sql sql-server tsql


【解决方案1】:

我想为可能遇到相同问题的其他人发布最终对我有用的解决方案。下面的代码解决了这个问题。

DROP PROCEDURE IF EXISTS procedure_name;

DELIMITER $$

CREATE PROCEDURE procedure_name ()
BEGIN
    DROP TEMPORARY TABLE IF EXISTS accounts;

    CREATE TEMPORARY TABLE accounts AS (
        SELECT  d.data_id                   
               ,p.pp_name AS name                              
               ,1 AS flag             
               ,d.pd_date
               ,DATE_FORMAT(pd_date,'%Y%m%d') AS date_period               
               ,CONVERT(varchar(3),0) AS n_phones                                  
       FROM    table_detail d                  
           JOIN    table_pool p ON d.pp_id = p.pp_id                   
           JOIN    table_type t ON p.pp_type_id = t.pp_type_id                                 
           JOIN    Inventory i ON d.data_id = i.data_id                    
           JOIN    Product pr ON i.product_id = pr.product_id  
       WHERE   pp_name IN (SELECT name FROM Sandbox..desired_sandbox)              
           AND TIMESTAMPDIFF(MONTH,pd_date,NOW()) < 3
    
    );
    
    -- Update the temp table based on specified criteria
    UPDATE accounts
        JOIN ...
        JOIN ...
    SET...
    WHERE...;

    -- Create final Query for report
    SELECT ...
    FROM accounts
    WHERE ...
    GROUP BY ... -- whatever you need for final query
    
    DROP TEMPORARY TABLE accounts; -- otherwise it survives the stored proc call
END
$$ -- signify end of block
DELIMITER ; -- reset to default delimiter

但是,重要的是要注意 MySQL 临时表的限制。虽然我没有在我的原始帖子中指出它,但后来,我试图将临时表加入到自身中。我需要遵循here 概述的建议。本质上,如果您需要自己引用临时表,则需要制作临时表的副本:CREATE TEMPORARY TABLE accounts2 AS (SELECT * FROM accounts)。然后你可以将一个临时表加入到自身中。

【讨论】:

    猜你喜欢
    • 2011-02-28
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    相关资源
    最近更新 更多