为什么此存储过程会提供与手动执行其内容不同的结果?

时间:2016-04-28 10:51:16

标签: mysql

这是一个简单的MySQL架构

CREATE TABLE Currency
(
     id          SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY
    ,code        CHAR(3) NOT NULL UNIQUE
    ,exponent    TINYINT NOT NULL
    ,sign        VARCHAR (5) NOT NULL DEFAULT '¤'
    ,ccx_enabled BOOLEAN NOT NULL DEFAULT FALSE
    ,is_fiat     BOOLEAN NOT NULL
);

CREATE TABLE `SiteAccount`
(
     id          INT NOT NULL AUTO_INCREMENT PRIMARY KEY
    ,currency    SMALLINT NOT NULL
    ,iban        VARCHAR (34) NULL DEFAULT NULL
    ,ethereum    CHAR (40) NULL DEFAULT NULL
    ,crypto_user INT NULL DEFAULT NULL
    ,FOREIGN KEY (currency)    REFERENCES Currency (id)
);

CREATE PROCEDURE SetUpUserEthereumAddress (id INT, addr TEXT)
INSERT INTO SiteAccount (currency, ethereum, crypto_user)
VALUES
(
    (SELECT id FROM Currency WHERE code='ETH'),
    addr,
    id
);

如果我调用存储过程,它会使用错误的货币创建一行。

INSERT INTO Currency (code, exponent, sign, is_fiat, ccx_enabled) VALUES
     ('GBP', 2, '£', 1, 1)
    ,('USD', 2, '$', 1, 1)
    ,('EUR', 2, '€', 1, 1)
    ,('ETH', 6, 'Ξ', 0, 1)
;

CALL SetUpUserEthereumAddress (1, '5bb0aa60d694714db16cbd3e3574c59d5ee4a95b');

select * from SiteAccount JOIN Currency on SiteAccount.currency=Currency.id;

creates a row货币为GBP而不是ETH。但是,如果我复制出存储过程的主体并手动替换参数,我会得到正确的结果。

INSERT INTO SiteAccount (currency, ethereum, crypto_user)
VALUES
(
    (SELECT id FROM Currency WHERE code='ETH'),
    '----aa60d694714db16cbd3e3574c59d5ee4a95b',
    2
);

select * from SiteAccount JOIN Currency on SiteAccount.currency=Currency.id;

这会按预期为货币ETH创建记录。

为什么存储过程选择/插入错误的货币ID?

1 个答案:

答案 0 :(得分:2)

当您在存储过程中时,id中的非限定SELECT id FROM Currency WHERE code='ETH'引用id表中的存储过程id参数,而不是Currency列。要引用表格列,您需要使用表格名称id来限定SELECT Currency.id FROM Currency WHERE code='ETH'