【问题标题】:Convert MS-SQL Server stored procedure to MySQL Query将 MS-SQL Server 存储过程转换为 MySQL Query
【发布时间】:2013-12-18 05:46:27
【问题描述】:

我在过去的一个小时里被困在这个问题上,无法将此 MSSQL Server 存储过程转换为“MySQL 查询”:

DECLARE @LedgerTbl TABLE (PARTY_ID VARCHAR(100),VRDATE VARCHAR(200),
                          VRNOA VARCHAR(200),ETYPE VARCHAR(50),
                          DESCRIPTION VARCHAR(500),DEBIT DECIMAL,
                          CREDIT DECIMAL, RunningTotal decimal) 

DECLARE @RunningTotal decimal 

SET @RunningTotal = 0 

INSERT INTO @LedgerTbl 
SELECT PARTY_ID,VRDATE,DCNO VRNOA,ETYPE,DESCRIPTION,DEBIT,CREDIT, null 
FROM PLEDGER WHERE PARTY_ID=@partyId AND VRDATE BETWEEN @from AND @to 
ORDER BY VRDATE,ETYPE,VRNOA 

UPDATE @LedgerTbl 
SET @RunningTotal = RunningTotal = @RunningTotal + (DEBIT-CREDIT) 
FROM @LedgerTbl 

SELECT * FROM @LedgerTbl 

如何将其转换为单个 MySQL 查询或 MySQL 存储过程?

更新

我试图将其转换为,但它给了我以下错误:

DELIMETER //

CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
    DECLARE RunningTotal DECIMAL;
    SET RunningTotal = 0;
    CREATE TEMPORARY TABLE LedgerTbl (PARTY_ID VARCHAR(100),VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL,RTotal decimal);
    INSERT INTO LedgerTbl 
    SELECT PARTY_ID,VRDATE,DCNO VRNOA,ETYPE,DESCRIPTION,DEBIT,CREDIT, null 
    FROM PLEDGER WHERE PARTY_ID=17 AND VRDATE BETWEEN '2013/12/02' AND '2010/12/02' 
    ORDER BY VRDATE,ETYPE,VRNOA; 

    UPDATE LedgerTbl 
    SET RunninTotal = RTotal = RunningTotal + (DEBIT-CREDIT) 
    FROM LedgerTbl; 

    SELECT * FROM LedgerTbl;
END//
DELIMETER;

以下是错误:

您的 SQL 查询中似乎有错误。下面的 MySQL 服务器错误输出,如果有的话,也可以帮助您诊断问题

错误:未知标点字符串@ 10 STR:// SQL:DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;DELIMETER//

创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;

SQL 查询:

DELIMETER// 创建过程Acc_Ledger () BEGIN DECLARE RunningTotal DECIMAL;

MySQL 说:文档

#1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册以获取正确的语法使用 'DELIMETER//

附近

创建过程Acc_Ledger () BEGIN 在第 1 行声明 RunningTotal'

有人可以评价一下吗?

【问题讨论】:

  • 如果您的意思是,在单个查询中执行完全相同的操作,您不能因为您的过程具有插入和更新操作。事实上,你不能在任何 RDBMS 中这样做。
  • 只需将其转换为 MySQL 存储过程即可。
  • @JorgeCampos 不可能使用子查询。对于您所说的插入和更新,它实际上并没有插入和更新。这里用来填充中间表@ledgerTbl只是为了达到目的。
  • 我没有时间做一个完整的移植,抱歉。此外,这对你来说也是很好的锻炼(前提是你是新手)。我将首先检查变量是如何在 MySQL 存储过程 (SP) 中声明的。 SP 逻辑的其余部分对我来说似乎并不太复杂。
  • 这两个参数是谁:@from AND @to

标签: mysql sql sql-server stored-procedures


【解决方案1】:

我必须自己编写这个过程,这里是帮助我理解 MySQL 中的存储过程的链接:http://net.tutsplus.com/tutorials/an-introduction-to-stored-procedures/。以及我想出的程序

DROP PROCEDURE IF EXISTS `Acc_Ledger`;

DELIMITER //

CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
    DECLARE RunningTotal, deb, cred DECIMAL(19,2);
    DECLARE counter, row_count int;

    SET RunningTotal = 0;
    SET counter = 1;

    DROP TABLE IF EXISTS LedgerTbl;

    CREATE TEMPORARY TABLE LedgerTbl (CTR int primary key auto_increment, PARTY_ID INT,VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL(19,2),CREDIT DECIMAL(19,2),RTotal DECIMAL(19,2));

    INSERT INTO LedgerTbl
    SELECT 0, PARTY_ID,VRDATE,DCNO,ETYPE,DESCRIPTION,DEBIT,CREDIT, null FROM PLEDGER WHERE PARTY_ID=17 AND VRDATE BETWEEN '2010/10/02' AND '2013/12/02' 
    ORDER BY VRDATE,ETYPE,DCNO;

    SELECT COUNT(*) INTO row_count FROM LedgerTbl;

    WHILE counter <= row_count DO

        SELECT debit INTO deb FROM LedgerTbl WHERE ctr = counter;
        SELECT credit INTO cred FROM LedgerTbl WHERE ctr = counter;
        SET RunningTotal = RunningTotal + (deb-cred);

        UPDATE LedgerTbl 
        SET LedgerTbl.RTotal = RunningTotal
        WHERE ctr = counter;  

        SET counter = counter + 1;

    END WHILE;

    SELECT * FROM LedgerTbl;
END//
DELIMITER ;

更新

现在我找到了比较有效的解决方案:

DROP PROCEDURE IF EXISTS `Acc_Ledger`;

DELIMITER //

CREATE PROCEDURE `Acc_Ledger` ()
BEGIN
    DECLARE RunningTotal, deb, cred DECIMAL(19,2);
    DECLARE counter, row_count int;

    SET RunningTotal = 0;
    SET counter = 1;

    DROP TABLE IF EXISTS LedgerTbl;

    CREATE TEMPORARY TABLE LedgerTbl (CTR int primary key auto_increment, PARTY_ID INT,VRDATE VARCHAR(200),VRNOA VARCHAR(200),ETYPE VARCHAR(50),DESCRIPTION VARCHAR(500),DEBIT DECIMAL(19,2),CREDIT DECIMAL(19,2),RTotal DECIMAL(19,2));

    INSERT INTO LedgerTbl
    SELECT 0, PARTY_ID,VRDATE,DCNO,ETYPE,DESCRIPTION,DEBIT,CREDIT, null FROM PLEDGER WHERE PARTY_ID=17 AND VRDATE BETWEEN '2010/10/02' AND '2013/12/02' 
    ORDER BY VRDATE,ETYPE,DCNO;

    SELECT COUNT(*) INTO row_count FROM LedgerTbl;

    SET @RunningTotal := 0;

    UPDATE LedgerTbl 
    SET RTotal = (@RunningTotal := @RunningTotal + (DEBIT - CREDIT));

    SELECT * FROM LedgerTbl;
END//
DELIMITER ;

【讨论】:

    【解决方案2】:

    MSSQL 过程似乎计算了一个运行总计,
    我已经在 sqlfiddle 上测试了这个过程(稍作修改),它给出了以下结果:
    http://www.sqlfiddle.com/#!6/0e909/1

    MSSQL 过程在这里可能包含一个错字:SELECT PARTY_ID,VRDATE,DCNO VRNOA,ETYPE, 尚不清楚 DCNO VRNOA 是两个单独的列,还是一列 DCNO_VRNOA 之间带有“缺失”下划线。
    我假设它们是两个独立的列。

    要在 MySql 中计算运行总计,无需使用临时表。
    这个简单的查询完成了这项任务:

    SELECT PARTY_ID,VRDATE,DCNO, VRNOA,ETYPE,DESCRIPTION,
           DEBIT,
           CREDIT, 
           @RunningTotal := @RunningTotal + (DEBIT-CREDIT) RunningTotal 
    FROM PLEDGER ,
         ( SELECT @RunningTotal:=0) init_variables
    WHERE PARTY_ID=1 
      AND VRDATE BETWEEN '2013-11-11' AND '2013-11-11'
    ORDER BY VRDATE,ETYPE,VRNOA; 
    

    在此处查看演示:--> http://www.sqlfiddle.com/#!2/daa6e/1

    该过程可能如下所示:

    DELIMITER /
    CREATE PROCEDURE `Acc_Ledger` ()
    BEGIN
        SELECT PARTY_ID,VRDATE,DCNO, VRNOA,ETYPE,DESCRIPTION,
               DEBIT,
               CREDIT, 
               @RunningTotal := @RunningTotal + (DEBIT-CREDIT) RunningTotal 
        FROM PLEDGER ,
             ( SELECT @RunningTotal:=0) init_variables
        WHERE PARTY_ID=1 
          AND VRDATE BETWEEN '2013-11-11' AND '2013-11-11'
        ORDER BY VRDATE,ETYPE,VRNOA; 
    END /
    DELIMITER ;
    

    【讨论】:

      猜你喜欢
      • 2011-02-15
      • 1970-01-01
      • 2011-03-06
      • 2013-10-10
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多