Хранимая процедура без конкатенации строк - PullRequest
0 голосов
/ 06 января 2012

Я использую SQL Server 2005/2008, у меня есть хранимая процедура, которая не использует конкатенацию строк для генерации оператора EXEC, но она использует динамическое имя для хранимой процедуры.

Я думаю, что @stored_procedure_name и, возможно, параметр @object_name оба уязвимы. Однако все ссылки на динамический SQL, которые я прочитал, предполагают, что вы объединяете свой оператор SQL внутри строки - поэтому мне интересно, может ли это быть на самом делеОК.

Обратите внимание, просто для публикации я сделал код универсальным, вызывая объекты таблицы - так что это не обязательно имеет логический смысл.

Вот код:

CREATE PROCEDURE [dbo].[my_dodgy_sp] 
    @object_name varchar(50) = 'All'
AS
BEGIN
    DECLARE @stored_procedure_name varchar(100);

    DECLARE object_cursor CURSOR FOR
        SELECT stored_procedure_name
        FROM [dbo].[objects]
        WHERE [stored_procedure_name] <> ''
        AND ([name] = @object_name)

    OPEN object_cursor

    FETCH NEXT FROM object_cursor 
        INTO @stored_procedure_name

    WHILE @@FETCH_STATUS = 0
       BEGIN

            EXEC @stored_procedure_name @object_id OUTPUT;

            FETCH NEXT FROM object_cursor
                INTO @stored_procedure_name
       END

    CLOSE object_cursor;
    DEALLOCATE object_cursor;
END

1 Ответ

1 голос
/ 06 января 2012

Попробуйте это:

CREATE PROCEDURE [dbo].[my_dodgy_sp] 
    @object_name varchar(50) = 'All'
AS
BEGIN
    DECLARE @stored_procedure_name sysname, @oID INT, @sql NVARCHAR(MAX), @object_id int;

    DECLARE object_cursor CURSOR FOR
        SELECT object_id, name
        FROM sys.procedures
        WHERE [name] = @object_name

    OPEN object_cursor

    FETCH NEXT FROM object_cursor 
        INTO @oID, @stored_procedure_name

    WHILE @@FETCH_STATUS = 0
       BEGIN
            SET @sql = N'EXEC ['+OBJECT_SCHEMA_NAME(@oid)+N'].['+@stored_procedure_name+N'] @Object_id OUTPUT'
            EXEC sp_executesql @sql, N'@object_id int OUTPUT', @ObjectId =@object_id OUTPUT

            PRINT @object_id -- we need to do smth with it?

            FETCH NEXT FROM object_cursor
                INTO @oID, @stored_procedure_name
       END

    CLOSE object_cursor;
    DEALLOCATE object_cursor;
END

НО

вместо того, чтобы использовать такой сложный способ, вы можете просто вызвать параметризованную процедуру?

...