场合/目标:
我有3个从1到[INT_MAX](SEQ_A,SEQ_B,SEQ_C)的整数序列,我想编写一个表值函数来从任一序列中获取一系列数字。
这是我提出的代码:
CREATE FUNCTION [dbo].[GetSequenceNumber]
(
@TabelField VARCHAR(256),
@Range INT
)
RETURNS @RETVALTABLE TABLE
(
SEQUENCE_NUMBER INT
)
AS
BEGIN
IF(ISNULL(@Range, 0) <= 0 OR @TabelField IS NULL)
RETURN;
DECLARE @FirstSeqNum sql_variant;
DECLARE @LastSeqNum sql_variant;
DECLARE @FirstSequenceNumber as INT;
DECLARE @LastSequenceNumber as INT;
IF @TabelField = 'FIELD_A' BEGIN
EXEC sys.sp_sequence_get_range N'SEQ_A', @Range, @FirstSeqNum OUTPUT, @LastSeqNum OUTPUT;
SET @FirstSequenceNumber = CONVERT(INT, @FirstSeqNum);
SET @LastSequenceNumber = CONVERT(INT, @LastSeqNum);
WHILE @FirstSequenceNumber <= @LastSequenceNumber BEGIN
INSERT INTO @RETVALTABLE SELECT @FirstSequenceNumber;
SET @FirstSequenceNumber += 1;
END
END
ELSE IF @TabelField = 'FIELD_B' BEGIN
EXEC sys.sp_sequence_get_range N'SEQ_B', @Range, @FirstSeqNum OUTPUT, @LastSeqNum OUTPUT;
SET @FirstSequenceNumber = CONVERT(INT, @FirstSeqNum);
SET @LastSequenceNumber = CONVERT(INT, @LastSeqNum);
WHILE @FirstSequenceNumber <= @LastSequenceNumber BEGIN
INSERT INTO @RETVALTABLE SELECT @FirstSequenceNumber;
SET @FirstSequenceNumber += 1;
END
END
ELSE IF @TabelField = 'FIELD_C' BEGIN
EXEC sys.sp_sequence_get_range N'SEQ_C', @Range, @FirstSeqNum OUTPUT, @LastSeqNum OUTPUT;
SET @FirstSequenceNumber = CONVERT(INT, @FirstSeqNum);
SET @LastSequenceNumber = CONVERT(INT, @LastSeqNum);
WHILE @FirstSequenceNumber <= @LastSequenceNumber BEGIN
INSERT INTO @RETVALTABLE SELECT @FirstSequenceNumber;
SET @FirstSequenceNumber += 1;
END
END
RETURN
END
为什么我这样做:
问题:
我可以创建该函数,我可以改变它,但我无法执行它。 当我调用该函数时,我总是得到错误: “只能在函数内执行函数和某些扩展存储过程。”
嗯,错误是非常自我解释,问题可能是EXEC sys.sp_sequence_get_range N'SEQ_X', @Range, @FirstSeqNum OUTPUT, @LastSeqNum OUTPUT;
部分。
问题:
如何摆脱错误?有没有比使用表值函数更好的方法来实现目标?
这里的首要任务是从特定序列(而不仅仅是起点和终点)获取某个范围内的所有数字。
(解决方案应适用于Microsoft SQL Server 2012及更高版本)
答案 0 :(得分:0)
没有进入对sproc的调用(MSSQL立即开始大喊大叫并且没有停止(OUTPUT
关键字,在函数内部调用proc),我想我已经找到了你这里。
此代码将返回范围中的值,而不会实际递增序列(尽管该方法是迭代的而不是基于集合的。我现在尝试设置基础):
CREATE FUNCTION dbo.GetSeqRange(@seqname VARCHAR(MAX), @start INT, @end INT)
RETURNS @ReturnTable TABLE (
ReturnValue INT
)
AS
BEGIN
DECLARE @increment INT = (SELECT CONVERT(INT, increment) FROM sys.sequences WHERE [name] = @seqname)
DECLARE @i INT = @start
WHILE @i <= @end
BEGIN
INSERT @ReturnTable VALUES(@i)
SET @i += @increment
END
RETURN
END
要递增序列,您可以用WHILE
替换SELECT NEXT VALUE FOR <seqname>
块的内部,并将其插入结果表中。如果有帮助,请告诉我!或者,如果我误解了你,那么我就会修改。