2015-08-20 3 views
1

я пытался сохранить динамический запрос внутри IF EXISTS условий в SQL Serverместо динамический запрос внутри IF EXISTS условия

create procedure temp_order 
(
@tbl varchar (max) 
) 
as 
begin 
IF EXISTS ('SELECT * FROM ' + @tbl + ' where cd = 1') 
end 

, но это выглядит как динамический запрос не будет работать в «IF EXISTS» состояние, любые способы сделать условие, если таблицы существуют или нет?

+0

Это не выполняет запрос. Это просто строка. Измените sql, чтобы выбрать Top (1) 1 из '+ @tbl +', где cd = 1 '. Выполните его и присвойте результат переменной. Затем проверьте значение. –

+2

НЕ выполняйте непосредственно sql, если часть динамической строки указана из параметра. Это определение учебника для SQL-инъекции. –

ответ

0

Попробуйте:

DECLARE @I TABLE(I INT) 
declare @sql varchar(1000) = 'select top(1) 1 from ' + @tbl + ' with(nolock) where cd = 1' 
INSERT INTO @i EXEC (@sql) 
IF EXISTS (select 1 from @i) Print 'exists' else print 'doesn''t exist' 

Если это подходит для вашей потребности, то в зависимости от источника параметра, посмотрим, что «защитные меры», чтобы принять для защиты от инъекций и тому подобное.

+0

это склонно к атаке в sql-инъекции: S –

+0

Только если у вас нет контроля над источником отправленных параметров. И почему я также заметил, что сначала вижу, помогает ли это в качестве доказательства концепции. Если, например, источником параметра является внутренний запрос, то нет никакой опасности. Вы не можете просто публиковать «sql injection» на каждом динамическом sql и отменить его. Это инструмент. И очень эффективный при правильном использовании. –

+0

Да При правильном использовании и, конечно же, с тех пор, как он подвержен SQL-инъекциям, ваша идея контроля над значениями параметров не имеет смысла, как только ваш код находится на производстве, я не знаю, как вы можете иметь контроль над чем угодно, кроме того, чтобы сделать ваш код настолько хорошим, что он может стоять на своем месте, они говорят: «Если он может пойти не так, это пойдет не так» –

0

Для этого вам понадобится динамический sql, но используйте динамический sql с функцией sp_executesql и quotename, как показано ниже, иначе код, возможно, подвержен атаке sql-injection.

create procedure temp_order 
(
    @tbl SYSNAME, --<-- use appropriate data type 
    @Exists INT OUTPUT 
) 
as 
begin 
Declare @Sql NVARCHAR(MAX); 

    SET @Sql = N'IF EXISTS(SELECT * FROM ' + QUOTENAME(@tbl) 
        + N' where cd = 1)' 
      + N'BEGIN 
       SET @Exists = 1; 
       END 
       ELSE 
       BEGIN 
       SET @Exists = 0; 
       END' 

    Exec sp_executesql @sql 
        ,N'@Exists INT OUTPUT' 
        ,@Exists OUTPUT 

end 
Смежные вопросы