一个SQL函数的问题。。。大神们速度进!江湖救急

寒飞a 2012-04-10 03:04:41
我在写一个SQL函数,比如函数为xxx 通过xxx(表名,表字段,字符串)的格式,我得到一个当前最新的编号,然后给施工单自动进行编号。在数据里实现,如: select xxx(business,number,'GD') 如果当前business表当前月份的编号排到GD12(04)-0233了,那么我这个函数直接返回 GD12(04)-0234
以下是SQL代码

ALTER FUNCTION [dbo].[GETBUSINESSNUMBER]
(@TABLENAME VARCHAR(50),@FILEDNAME VARCHAR(50),@STR VARCHAR(10))
--第一个参数为表明,第二个参数为字段名,第三个参数为一个字符串,如GD。
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @NUMBER VARCHAR(100);--声明一个最终返回值的变量
DECLARE @YEAS VARCHAR(10);--当前年
DECLARE @MOTH VARCHAR(10);--当前月
DECLARE @S INT;--中间变量
SET @YEAS=RIGHT(DATENAME(yy,GETDATE()),2);--得到年
SET @MOTH=DATENAME(mm,GETDATE());--得到月
SET @NUMBER=@STR+@YEAS+'('+@MOTH+')-';--得到一个字符串 如 GD12(04)- 这样的
DECLARE @SQLSTR VARCHAR(300);--声明一个变量的SQL语句,
SET @SQLSTR='SELECT @S=MAX(RIGHT('+@FILEDNAME+',4)) FROM '+QUOTENAME(@TABLENAME);
SET @SQLSTR=@SQLSTR+' WHERE LEFT('+@FILEDNAME+',9)='+''''+@NUMBER+'''';
--这里是对SQL语句进行拼接,查询到所在表的最大编号。
EXEC @SQLSTR;--这里来执行。注意不是EXEC(@sqlstr),这样会报错,不知道为什么
--SELECT @S=MAX(RIGHT(@FILEDNAME,4)) FROM @TABLENAME WHERE @FILEDNAME=@NUMBER;
--为什么我不用上面屏蔽掉的这一句,直接简单,我发觉会报一个让声明表变量的错误。因为@TABLENAME是传入的一个字符串,结果就好比
--SELECT * FROM 'CUSTOMER'一样,会报错,没找到解决方法
SET @NUMBER=@NUMBER+dbo.PadLeft(STR(@S+1),'0',4);--这里是另外一个补白的函数 ,如返回88 转换橙0088.
RETURN @NUMBER;
END
GO


...全文
252 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
寒飞a 2012-04-12
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]
o ,函数内部不能调用sp_executesql 之类的,你还是改为存储过程吧
[/Quote]
存储过程不能有返回值吧。!!!
  • 打赏
  • 举报
回复
o ,函数内部不能调用sp_executesql 之类的,你还是改为存储过程吧
寒飞a 2012-04-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
楼主可以使用profile跟踪一下,看最终执行的sql是什么,看该sql是否有问题
[/Quote]

在吗?我按照你的要求改了,函数修改成功了,执行函数依然报错。报另外一个了 。

消息 557,级别 16,状态 2,第 2 行
只有函数和扩展存储过程才能从函数内部执行。
寒飞a 2012-04-10
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
SQL code

DECLARE @IntVariable int;
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE @max_title varchar(30);

SET @IntVariable = 197;
SET @SQLString = N'SELECT ……
[/Quote]

我有点看不懂这个,我没用过sp_executesql。能直接帮我修改下我的代码吗。我真的很着急。。。。
  • 打赏
  • 举报
回复
DECLARE @IntVariable int;
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE @max_title varchar(30);

SET @IntVariable = 197;
SET @SQLString = N'SELECT @max_titleOUT = max(JobTitle)
FROM AdventureWorks2012.HumanResources.Employee
WHERE BusinessEntityID = @level';
SET @ParmDefinition = N'@level tinyint, @max_titleOUT varchar(30) OUTPUT';

EXECUTE sp_executesql @SQLString, @ParmDefinition, @level = @IntVariable, @max_titleOUT=@max_title OUTPUT;
SELECT @max_title;
寒飞a 2012-04-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
使用sp_executesql
[/Quote]
能说说具体怎么修改吗

代码:


ALTER FUNCTION [dbo].[GETBUSINESSNUMBER]
(@TABLENAME VARCHAR(50),@FILEDNAME VARCHAR(50),@STR VARCHAR(10))
--第一个参数为表明,第二个参数为字段名,第三个参数为一个字符串,如GD。
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @NUMBER VARCHAR(100);--声明一个最终返回值的变量
DECLARE @YEAS VARCHAR(10);--当前年
DECLARE @MOTH VARCHAR(10);--当前月
DECLARE @S INT;--中间变量
SET @YEAS=RIGHT(DATENAME(yy,GETDATE()),2);--得到年
SET @MOTH=DATENAME(mm,GETDATE());--得到月
SET @NUMBER=@STR+@YEAS+'('+@MOTH+')-';--得到一个字符串 如 GD12(04)- 这样的
DECLARE @SQLSTR VARCHAR(300);--声明一个变量的SQL语句,
SET @SQLSTR='SELECT @S=MAX(RIGHT('+@FILEDNAME+',4)) FROM '+QUOTENAME(@TABLENAME);
SET @SQLSTR=@SQLSTR+' WHERE LEFT('+@FILEDNAME+',9)='+''''+@NUMBER+'''';
EXEC @SQLSTR;
--SELECT @S=MAX(RIGHT(@FILEDNAME,4)) FROM @TABLENAME WHERE @FILEDNAME=@NUMBER;
SELECT @S=MAX(RIGHT(CC_NUMBER,4)) FROM [Construction] WHERE LEFT(CC_NUMBER,9)='GD12(04)-'
SET @NUMBER=@NUMBER+dbo.PadLeft(ltrim(STR(@S+1)),'0',4);--这里是另外一个补白的函数 ,如返回88 转换橙0088.
RETURN @NUMBER;
END

寒飞a 2012-04-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
SELECT @S=MAX(RIGHT(CC_NUMBER,4)) FROM [Construction] WHERE LEFT(CC_NUMBER,9)='GD12(04)-'

执行有问题吗?
[/Quote]



set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER FUNCTION [dbo].[GETBUSINESSNUMBER]
(@TABLENAME VARCHAR(50),@FILEDNAME VARCHAR(50),@STR VARCHAR(10))
--第一个参数为表明,第二个参数为字段名,第三个参数为一个字符串,如GD。
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @NUMBER VARCHAR(100);--声明一个最终返回值的变量
DECLARE @YEAS VARCHAR(10);--当前年
DECLARE @MOTH VARCHAR(10);--当前月
DECLARE @S INT;--中间变量
SET @YEAS=RIGHT(DATENAME(yy,GETDATE()),2);--得到年
SET @MOTH=DATENAME(mm,GETDATE());--得到月
SET @NUMBER=@STR+@YEAS+'('+@MOTH+')-';--得到一个字符串 如 GD12(04)- 这样的
--DECLARE @SQLSTR VARCHAR(300);--声明一个变量的SQL语句,
--SET @SQLSTR='SELECT @S=MAX(RIGHT('+@FILEDNAME+',4)) FROM '+QUOTENAME(@TABLENAME);
--SET @SQLSTR=@SQLSTR+' WHERE LEFT('+@FILEDNAME+',9)='+''''+@NUMBER+'''';
--这里是对SQL语句进行拼接,查询到所在表的最大编号。
--EXEC @SQLSTR;--这里来执行。注意不是EXEC(@sqlstr),这样会报错,不知道为什么
--SELECT @S=MAX(RIGHT(@FILEDNAME,4)) FROM @TABLENAME WHERE @FILEDNAME=@NUMBER;
--如果直接这样来查询,会报一个没有表变量的错误

SELECT @S=MAX(RIGHT(CC_NUMBER,4)) FROM [Construction] WHERE LEFT(CC_NUMBER,9)='GD12(04)-'
SET @NUMBER=@NUMBER+dbo.PadLeft(ltrim(STR(@S+1)),'0',4);--这里是另外一个补白的函数 ,如返回88 转换橙0088.
RETURN @NUMBER;
END
GO


select dbo.[GETBUSINESSNUMBER]('Construction','CC_NUMBER','GD')
直接返回了GD12(04)-0089 完美无错、
  • 打赏
  • 举报
回复
使用sp_executesql
寒飞a 2012-04-10
  • 打赏
  • 举报
回复

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER FUNCTION [dbo].[GETBUSINESSNUMBER]
(@TABLENAME VARCHAR(50),@FILEDNAME VARCHAR(50),@STR VARCHAR(10))
--第一个参数为表明,第二个参数为字段名,第三个参数为一个字符串,如GD。
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @NUMBER VARCHAR(100);--声明一个最终返回值的变量
DECLARE @YEAS VARCHAR(10);--当前年
DECLARE @MOTH VARCHAR(10);--当前月
DECLARE @S INT;--中间变量
SET @YEAS=RIGHT(DATENAME(yy,GETDATE()),2);--得到年
SET @MOTH=DATENAME(mm,GETDATE());--得到月
SET @NUMBER=@STR+@YEAS+'('+@MOTH+')-';--得到一个字符串 如 GD12(04)- 这样的
--DECLARE @SQLSTR VARCHAR(300);--声明一个变量的SQL语句,
--SET @SQLSTR='SELECT @S=MAX(RIGHT('+@FILEDNAME+',4)) FROM '+QUOTENAME(@TABLENAME);
--SET @SQLSTR=@SQLSTR+' WHERE LEFT('+@FILEDNAME+',9)='+''''+@NUMBER+'''';
--这里是对SQL语句进行拼接,查询到所在表的最大编号。
--EXEC @SQLSTR;--这里来执行。注意不是EXEC(@sqlstr),这样会报错,不知道为什么
SELECT @S=MAX(RIGHT(@FILEDNAME,4)) FROM @TABLENAME WHERE @FILEDNAME=@NUMBER;
--如果直接这样来查询,会报一个没有表变量的错误
SET @NUMBER=@NUMBER+dbo.PadLeft(STR(@S+1),'0',4);--这里是另外一个补白的函数 ,如返回88 转换橙0088.
RETURN @NUMBER;
END
GO




消息 1087,级别 15,状态 2,过程 GETBUSINESSNUMBER,第 20 行
必须声明表变量 "@TABLENAME"。
  • 打赏
  • 举报
回复
SELECT @S=MAX(RIGHT(CC_NUMBER,4)) FROM [Construction] WHERE LEFT(CC_NUMBER,9)='GD12(04)-'

执行有问题吗?
寒飞a 2012-04-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
楼主可以使用profile跟踪一下,看最终执行的sql是什么,看该sql是否有问题
[/Quote]

该sql就是 'SELECT @S=MAX(RIGHT(CC_NUMBER,4)) FROM [Construction] WHERE LEFT(CC_NUMBER,9)='GD12(04)-'

如果直接将这句放进函数体的话,肯定是没问题的。我也试过。完全没问题。
寒飞a 2012-04-10
  • 打赏
  • 举报
回复
我查了下。不是有效的标识符。则EXEC的时候加上() 改成 exec(@SQLSTR),但是这样的话,直接不能建立函数了。会报另外一个错误。
消息 443,级别 16,状态 14,过程 GETBUSINESSNUMBER,第 19 行
在函数内的 'EXECUTE STRING' 中对带副作用的或依赖于时间的运算符的使用无效


  • 打赏
  • 举报
回复
楼主可以使用profile跟踪一下,看最终执行的sql是什么,看该sql是否有问题
寒飞a 2012-04-10
  • 打赏
  • 举报
回复
如果现在执行,select dbo.[GETBUSINESSNUMBER]('Construction','CC_NUMBER','GD')

会报错误。错误为:
消息 203,级别 16,状态 2,第 1 行
名称 'SELECT @S=MAX(RIGHT(CC_NUMBER,4)) FROM [Construction] WHERE LEFT(CC_NUMBER,9)='GD12(04)-'' 不是有效的标识符。

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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