Ошибка SQL при попытке зацикливания в базах данных и создания функции - PullRequest
0 голосов
/ 20 мая 2019

Я создал сценарий SQL для циклического отбрасывания баз данных и создания функции (цель функции - преобразовать RTF в обычный текст). Я помещаю сценарий создания функции в переменную и пытаюсь выполнить его с помощью команды exec.

Я использовал цикл While, и я поместил запрос в переменную varchar, затем, exec @command

но я получаю эту ошибку:

введите описание изображения здесь

declare @Total as int

select @Total = count(*) from Temp1
declare @counter as int
set @counter = 1

declare @CurrentVal as varchar(max)
declare @command varchar(max)

while (@counter <= @Total)
begin 

select @CurrentVal = name from Temp1 where RowId = @counter
set @command=' use '+@CurrentVal+'
GO
CREATE FUNCTION dbo.fnParseTEXTRTF
(
@rtf VARCHAR(max)
)
RETURNS VARCHAR(max)
AS
BEGIN


DECLARE @Stage TABLE
(
Chr CHAR(1),
Pos INT
)

INSERT @Stage
(
Chr,
Pos
)
SELECT SUBSTRING(@rtf, Number, 1),
Number
FROM master..spt_values
WHERE Type = ''p''
AND SUBSTRING(@rtf, Number, 1) IN (''{'', ''}'')

DECLARE @Pos1 INT,
@Pos2 INT

SELECT @Pos1 = MIN(Pos),
@Pos2 = MAX(Pos)
FROM @Stage

DELETE
FROM @Stage
WHERE Pos IN (@Pos1, @Pos2)

WHILE 1 = 1
BEGIN
SELECT TOP 1 @Pos1 = s1.Pos, @Pos2 = s2.Pos
FROM @Stage AS s1
INNER JOIN @Stage AS s2 ON s2.Pos > s1.Pos
WHERE s1.Chr = ''{''
AND s2.Chr = ''}''
ORDER BY s2.Pos - s1.Pos

IF @@ROWCOUNT = 0
BREAK

DELETE
FROM @Stage
WHERE Pos IN (@Pos1, @Pos2)

UPDATE @Stage
SET Pos = Pos - @Pos2 + @Pos1 - 1
WHERE Pos > @Pos2

SET @rtf = STUFF(@rtf, @Pos1, @Pos2 - @Pos1 + 1, '''')
END

SET @Pos1 = PATINDEX(''%\cf[0123456789][0123456789 ]%'', @rtf)

WHILE @Pos1 > 0
SELECT @Pos2 = CHARINDEX('' '', @rtf, @Pos1 + 1), @rtf = STUFF(@rtf, @Pos1, @Pos2 - @Pos1 + 1, ''''), @Pos1 = PATINDEX(''%\cf[0123456789][0123456789 ]%'', @rtf)

SELECT @rtf = REPLACE(@rtf, ''\pard'', ''''), @rtf = REPLACE(@rtf, ''\par'', ''''), @rtf = case when LEN(@rtf)>0 then LEFT(@rtf, LEN(@rtf) - 1) else @rtf end

SELECT @rtf = REPLACE(@rtf, ''\b0 '', ''''), @rtf = REPLACE(@rtf, ''\b '', '''')

SELECT @rtf = STUFF(@rtf, 1, CHARINDEX('' '', @rtf), '''')


RETURN @rtf
end'
set @counter = @counter + 1  
exec  @command
end

1 Ответ

0 голосов
/ 21 мая 2019

Как я понимаю, функция правильная, основная проблема - выполнить оператор для создания функции в нескольких базах данных.GO не может использоваться здесь, это не sql, это инструкция для клиента выполнить все операторы в области видимости. К сожалению, вы не можете создать функцию вне текущей базы данных, используя [DatabaseName]. [Schema]. [FuncName].Я могу предложить такую ​​технику для решения проблемы, например, код

declare @funccode nvarchar(4000);
set @funccode='CREATE FUNCTION [dbo].[fntest]
(
)
RETURNS int
AS
BEGIN
    RETURN 1
END;'

declare @dbname nvarchar(100)='TestDatabase'

declare @statement nvarchar(max) ='use '+@dbname+';
exec (@func);'

exec sp_executesql  @stmt = @statement,@params=N'@func nvarchar(4000)',@func=@funccode;

Th идея - переключить текущую базу данных внутри оператора exec и вызвать новый оператор exec, когда текущая база данных уже установлена ​​

...