2014-10-11 57 views
-2

嗨我是新来的MySQL数据库编程,我试图创建一个过程,但它failes,给我的错误一样架构错误在MySQL

架构创建失败:您在您的SQL语法错误;检查对应于你的MySQL服务器版本在4号线附近使用“”正确的语法手册:

代码现在用的就是

CREATE TABLE CUSTOMERS(
    ID INT    NOT NULL, 
    NAME VARCHAR (20)  NOT NULL, 
    AGE INT    NOT NULL, 
    ADDRESS CHAR (25) , 
    SALARY DECIMAL (18, 2), 
    PRIMARY KEY (ID) 
); 


INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (1,'aff',2,3,5); 



CREATE PROCEDURE doiterate(p1 INT) 
BEGIN 
set p1 = 'ID'; 
select p1 from CUSTOMERS; 
END; 

..What我在这里做用于使。语法错误?任何人都可以指出我的错误...

感谢名单

+0

不相关,但是,你最有可能做**不**需要'字符',但'varchar'。 'char'列总是用空格填充到定义的长度。所以如果你在'char(10)'列中存储''1',数据库将会存储''1'填充9个空格字符。 – 2014-10-11 06:48:59

回答

2

这就是答案:

DELIMITER $$ 

CREATE PROCEDURE `test`.`new_procedure` (p1 INT) 
BEGIN 
set p1 = 'ID'; 
select p1 from CUSTOMERS; 
END $$ 

DELIMITER ; 
+0

让我加一点解释:当创建一个过程时,你必须用一个自定义的(在本例中为'$$')替换默认的句子终结符';',这样你就可以使用默认的终止符在你的过程中写入指令。你的程序完成后,你必须用自定义终止程序结束程序,然后恢复默认程序,这样你就可以继续以通常的方式编写查询和指令了。 – Barranka 2014-10-11 07:02:23

+0

@Barranka它根本没有帮助我..可以请你在sql小提琴上发布一个工作示例 – 2014-10-11 07:26:46

+0

@ 4EACH没有这没有工作..它引发了同样的错误..如果你在sql提琴上发布工作示例 – 2014-10-11 07:28:18

0

仔细阅读您的问题后,我想我已经想通了。

4EACH's answer是正确的分隔符的事情(我相应地评论)。但是还有一些误会:

首先,您试图将文本值分配给p1,并且它已在您的过程中定义为INT参数!如果你希望它是一个文本值,你需要在你的程序开始时声明它。其次,你正试图在程序内部建立一个动态的SQL表达式......而这不是做到这一点的方法!如果你想这样做,你需要使用准备好的语句。

一个可能的解决方案:

DELIMITER $$ 

CREATE PROCEDURE new_procedure() 
BEGIN 
    declare p1 varchar; 
    declare sql text; 

    set p1 = 'ID'; 
    set sql = concat('select `', p1, '` from CUSTOMERS'); 
    prepare stmt from sql; 
    execute stmt; 
END $$ 

DELIMITER ; 

好吧,我会留下上面的代码,因为它是,但我必须说:这是错误Quoting from the reference manual

以后在程序之外执行的存储程序上下文准备,因为他们走出去的程序结束时的范围,将是不可用的是语句不能引用存储过程或函数的参数或局部变量的声明。作为一种解决方法,请参阅用户定义的变量,该变量也具有会话范围;见Section 9.4, “User-Defined Variables”

所以,重点是:如果你想定义这种事情,那么你必须使用用户变量。请注意,他们都没有宣布,但在第一个任务被初始化:

DELIMITER $$ 

CREATE PROCEDURE new_procedure() 
BEGIN 
    set @p1 = 'ID'; 
    set @sql = concat('select `', p1, '` from CUSTOMERS'); 
    prepare stmt from @sql; 
    execute stmt; 
END $$ 

DELIMITER ; 

是的,here is your SQL fiddle example


回答您的评论:

但我怎么能传递列名称在变量中?

这里有一个办法:

delimiter $$ 
CREATE PROCEDURE new_procedure (col varchar(255)) 
BEGIN 
    set @p1 = col; 
    set @sql = concat('select `', @p1, '` from CUSTOMERS'); 
    prepare stmt from @sql; 
    execute stmt; 
END $$ 
delimiter ; 

And here's the example


使用存储过程做这样的事情是......麻烦,因为你需要准备在其内部声明,但要做到这一点,必须使用增加过程范围的用户变量(不能使用局部变量来创建预准备语句)。如果你想这样做没有程序,你可以做这样的事情:

set @cols = 'id, name'; -- If you want, enclose them in back-ticks: '`id`, `name`' 
set @sql = concat_ws(' ', 'select', @cols, 'from your_table'); 
prepare stmt from @sql; 
execute stmt; 
-- When you are done, deallocate the prepared statement 
deallocate prepare stmt; 
+0

..没有它的问题..我得到同样的错误..可以运行这个代码在SQL小提琴.. ??当我运行它我得到错误 – 2014-10-11 07:39:01

+0

问题是在这里我认为是delimeter的情况.. – 2014-10-11 07:40:43

+0

使用phpmyadmin或mysql工作台,我在sqlfiddle中得到的错误,我不能运行PROCEDURE :) – 4EACH 2014-10-11 07:41:49