mysql function 语法问题

wzhiyuan 2010-07-21 10:20:17
大家好,我是mysql 新学者,我写了一个function 编译总是提示语法错误,甚至我把全部行都注释掉也是错误,大家谁指点一下哪里错了?
CREATE DEFINER = CURRENT_USER FUNCTION `getCategoryPath`(
catid INTEGER
)
RETURNS VARCHAR(255)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
declare path varchar(255) ;
--if catid=0 then
-- set path='';
--else
-- declare catname varchar(255);
-- declare parentid INTEGER;
-- select cat_name INTO catname, parent_id into parentid
-- from 365mask_category where cat_id = catid;
-- set path=getCategoryPath(parentid)+'>'+catname;
--end if;
RETURN path;
END ;
...全文
1295 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ACMAIN_CHM 2010-07-22
  • 打赏
  • 举报
回复
wzhiyuan 2010-07-22
  • 打赏
  • 举报
回复
以上是我在MSSQL SERVER下建的一个例子,由于这个问题关心的是getCategoryPath(catid)这个函数,所以其它的比如索引,触发器维护PATH这个字段,等,这些问题暂时不提。

我现在奇怪的是,为什么同样的逻辑实现,getCategoryPath(catid)在MYSQL中得不到想要的结果。
原谅我的MYSQL语法不熟悉,写出同样的建表和填充数据语句有点困难,如果需要,你们可以用我上面的T-sqL稍改一下。

我的MYSQL版本是5.1.
zuoxingyu 2010-07-22
  • 打赏
  • 举报
回复

CREATE DEFINER = CURRENT_USER FUNCTION `getCategoryPath`(
catid INTEGER
)
RETURNS VARCHAR(255)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
declare path varchar(255) ;
-- if catid=0 then
-- set path='';
-- else
-- declare catname varchar(255);
-- declare parentid INTEGER;
-- select cat_name INTO catname, parent_id into parentid
-- from 365mask_category where cat_id = catid;
-- set path=getCategoryPath(parentid)+'>'+catname;
-- end if;
RETURN path;
END ;


用-- 注释的时候,后面要带一个空格。
wzhiyuan 2010-07-21
  • 打赏
  • 举报
回复
我的表是一个树型的分类表,结构是有四个字段(自增ID,类名,父ID,路径)。虽然从逻辑上说路径是一个非独立字段,可在查询时通过父ID递归或循环得出,不需要单独存储,但为了提高查询效率,可将他求出做为一个独立字段存储。我现在需要的就是这个求路径的MYSQL函数。

我先给出我在MSSQL SERVER下的实现。

CREATE TABLE [dbo].[Categories](
[ID] [int] IDENTITY(0,1) NOT NULL,
[CategoryName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
[PID] [int] NULL CONSTRAINT [DF_Categories_PID] DEFAULT ((0)),
[Path] [nvarchar](1000) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
USE [mytb]
GO
ALTER TABLE [dbo].[Categories] WITH CHECK ADD CONSTRAINT [FK_Categories_Categories] FOREIGN KEY([PID])
REFERENCES [dbo].[Categories] ([ID])

GO

Insert into Categories(CategoryName) values('Root')
insert into Categories(CategoryName,pid) values('Animals',0)
insert into Categories(CategoryName,pid) values('Cat',1)
insert into Categories(CategoryName,pid) values('Dog',1)
insert into Categories(CategoryName,pid) values('Plants',0)
insert into Categories(CategoryName,pid) values('Vegetables',4)
insert into Categories(CategoryName,pid) values('Tomato',5)

go

CREATE FUNCTION [dbo].[getCategoryPath]
(
-- Add the parameters for the function here
@id int
)
RETURNS nvarchar(1000)
AS
BEGIN
-- Declare the return variable here
DECLARE @path nvarchar(1000)
-- Add the T-SQL statements to compute the return value here
set @path=''

while @id>0
begin
SELECT @id=pid,@path=categoryname+' > '+@path from Categories where id=@id
end
select @path=categoryname+' > '+@path from Categories where id=0

return @path
END


go

update categories set path=dbo.getCategoryPath(id)

select * from categories

-----------以下是表结果----------
-id------类名-------父ID----路径----------------
0 Root 0 Root >
1 Animals 0 Root > Animals >
2 Cat 1 Root > Animals > Cat >
3 Dog 1 Root > Animals > Dog >
4 Plants 0 Root > Plants >
5 Vegetables 4 Root > Plants > Vegetables >
6 Tomato 5 Root > Plants > Vegetables > Tomato >
WWWWA 2010-07-21
  • 打赏
  • 举报
回复
DELIMITER $$
CREATE FUNCTION `getCategoryPath`(
catid INTEGER
)
RETURNS VARCHAR(255)
BEGIN
DECLARE catname VARCHAR(255);
DECLARE parentid INTEGER;
DECLARE path VARCHAR(255) ;
IF catid=0 THEN
SET path='';
ELSE
SELECT cat_name , parent_id INTO catname,parentid
FROM 365mask_category WHERE cat_id = catid;
SET path=CONCAT(getCategoryPath(parentid),'>',catname);
END IF;
RETURN path;
END $$;
递归查询?
ACMAIN_CHM 2010-07-21
  • 打赏
  • 举报
回复
提供你的建表语句和测试数据,这样别人可以直接进行调试。

建议你列出你的表结构,并提供测试数据以及基于这些测试数据的所对应正确结果。
参考一下这个贴子的提问方式http://topic.csdn.net/u/20091130/20/8343ee6a-417c-4c2d-9415-fa46604a00cf.html

1. 你的 create table xxx .. 语句
2. 你的 insert into xxx ... 语句
3. 结果是什么样,(并给以简单的算法描述)
4. 你用的数据库名称和版本(经常有人在MS SQL server版问 MySQL)

这样想帮你的人可以直接搭建和你相同的环境,并在给出方案前进行测试,避免文字描述理解上的误差。

wzhiyuan 2010-07-21
  • 打赏
  • 举报
回复
我原来的不知道为什么,把内容全部注释掉也通不过,后来,我没办法,新建了一个空函数,一句一句把我写的加上去,最后才创建成功。当然,一些语法错误,如select into,concat 这些基本上按wwwa,的提示更正了。
但是,创建成功后,运行函数,却得不到需要的结果,select getCategoryPath(0),可以得到空字符串,非0参数,总是没有任何返回值(数据没问题),我怀疑是递归的问题,但是没法确定。于是我把递归改成了循环,如下所示,但是也总是不能正确返回值。

BEGIN
declare path varchar(255);
declare catname varchar(50);
set path='';
WHILE catid > 0 DO
select parent_id, CONCAT(catname,'>',path) into catid, path
from 365mask_category where cat_id = catid;
END WHILE;

RETURN path;
END;

这样改之后,同样返不回需要的值。

郁闷死了,这个问题搞了快一天了。在MS sqlserver里,类似这样写没有任何问题的,在MYSQL里,不知道哪里错了
ACMAIN_CHM 2010-07-21
  • 打赏
  • 举报
回复
测试没有任何问题啊,你是不是没有加上 DELIMITER // ? 另外注释-- 后必须有一个空格。

mysql> DELIMITER //
mysql> CREATE FUNCTION `getCategoryPath`(
-> catid INTEGER
-> )
-> RETURNS VARCHAR(255)
-> NOT DETERMINISTIC
-> CONTAINS SQL
-> SQL SECURITY DEFINER
-> COMMENT ''
-> BEGIN
-> declare path varchar(255) ;
-> -- if catid=0 then
-> -- set path='';
-> -- else
-> -- declare catname varchar(255);
-> -- declare parentid INTEGER;
-> -- select cat_name INTO catname, parent_id into par
entid
-> -- from 365mask_category where cat_id = catid;
-> -- set path=getCategoryPath(parentid)+'>'+catname;
-> -- end if;
-> RETURN path;
-> END //
Query OK, 0 rows affected (0.28 sec)

mysql>
mysql> DELIMITER ;
mysql>

56,937

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧