Sql server 在SQL Server中将函数安全地转换为过程

Sql server 在SQL Server中将函数安全地转换为过程,sql-server,oracle,stored-procedures,Sql Server,Oracle,Stored Procedures,我一直在将oracle模式转换为sql server模式,并出现以下错误 在函数中无效使用副作用运算符“SET COMMAND” 在我的例子中,修改数据库涉及到这一点 set @originalDateFirst = @@DateFirst; set datefirst 1; set @DayOfWeek = datepart(weekday,@DATE); -- 1 to 5 = Weekday set datefirst originalDateFirst; 理想情况下,这

我一直在将oracle模式转换为sql server模式,并出现以下错误

在函数中无效使用副作用运算符“SET COMMAND”

在我的例子中,修改数据库涉及到这一点

  set @originalDateFirst = @@DateFirst;
  set datefirst 1;
  set @DayOfWeek = datepart(weekday,@DATE); -- 1 to 5 = Weekday
  set datefirst originalDateFirst;
理想情况下,这不会修改数据库,但是
datepart
函数使用静态

我不是一个真正的数据库背景,所以对此有点困惑,但阅读它看起来我需要做的只是将单词function替换为procedure,然后我就离开了。然而,我得到了以下错误

“RETURNS”附近的语法不正确

阅读一点有关存储过程的内容,不允许返回任何它们喜欢的内容—只返回整数。但是,整数通常与控制台应用程序的返回代码具有相同的语义-0表示成功,其他任何内容都是错误

幸运的是,我想要返回的类型是一个整数,因此修复了下一个错误:

“RETURNS”附近的语法不正确

只涉及删除

RETURNS INTEGER
从功能/程序。然而,我不确定是否有任何奇怪的副作用所造成的错误代码解释,将超出我的控制。该函数实际上只返回0或1,基本上作为true或false标志(其中1为true,0为false,正如您所期望的)。因此,我的一个返回值将计为“错误”

如果使用过程的返回代码而不是使用out参数会产生什么后果呢?这只是一个坏习惯吗?如果这样做是安全的,我当然更愿意这样做,因此我不需要更改任何调用代码。

这不是对您提出的问题的回答,但可能是解决整个问题的更好方法

与其依赖于特定的
DATEFIRST
设置,或者更改
DATEFIRST
设置,为什么不使用一个无论
DATEFIRST
设置如何都能返回可靠结果的表达式呢

例如,此表达式:

select (DATEPART(weekday,GETDATE()) + 7 - DATEPART(weekday,'20140406')) % 7
始终在周一返回1,周二返回2,…,周五返回5。无论什么设置生效

因此,您的整个原始代码块(由4行代码组成)可以是:

set @DayOfWeek = (DATEPART(weekday,@Date) + 7 -
                  DATEPART(weekday,'20140406')) % 7; -- 1 to 5 = Weekday
现在,您应该能够继续将其作为函数而不是存储过程编写


如果这样做是安全的,我当然更愿意这样做,所以我不需要更改任何调用代码

如果将函数更改为存储过程,则必须执行此操作。没有语法可以让您在查看调用时怀疑是否调用了存储过程或函数——它们总是使用不同的语法。一个过程的执行方式是作为批处理中的第一段文本,或者在前面加上
EXEC
关键字,不加括号

另一方面,函数在调用时必须始终应用括号,并且必须在较大语句中显示为表达式(例如
SELECT
)。您不能执行函数,也不能将其作为批处理中的第一段文本来调用函数。

输出参数可以是(几乎)任何有效的数据类型,返回值总是整数,不一定是0或1

因为不能将过程用作查询源(它不是表),所以要使用过程中的返回值,请声明一个变量并按如下方式执行过程:

create procedure p as
-- some code
return 13
go

declare @r int
exec @r = p
select @r
我不会称之为piggybacking,例如,它是返回成功/错误代码的常规方法。但是如何解释返回值完全取决于调用代码


函数otoh可以用作查询源(如果表有值),也可以用作select list或where子句中的标量值等。但您不能修改函数内的数据,并且函数还有其他限制(如您已经了解的)。此外,函数可能会对性能产生严重影响(内联表值函数除外,它们使用起来非常安全)。

不错!我想这实际上是我要选择的。我用了一些纸和笔的例子来了解那里的实际情况。它有点像一个解码环!谢谢你的回答!我想这可能比其他人更能回答底部的问题,但我把它奖励给了其他人,因为这对我更有用。很高兴知道返回值没有什么奇怪的地方。我以前从未遇到过这样的困境——通常最终会回答我自己的问题,它们在c#或wpf中通常都是模糊的!