5

この手順には3つのパラメータがあります。しかし、パラメーターを渡して実行しようとすると、エラーが表示されます。私を助けてください。

create procedure queryfunctions @Tabname varchar(150),@colname varchar(150),@valuesname varchar(150)
as
begin
declare @sql varchar(4000)
select @sql='select * from @Tabname where @colname=@valuesname'
exec(@sql)
end

exec queryfunctions 'education','eduChildName','Revathi'

エラー :

メッセージ1087、レベル15、状態2、行1テーブル変数「@Tabname」を宣言する必要があります。

4

2 に答える 2

15

これがはるかに安全な代替手段です:

ALTER PROCEDURE dbo.queryfunctions 
  @Tabname NVARCHAR(511),
  @colname NVARCHAR(128),
  @valuesname VARCHAR(150)
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @sql NVARCHAR(MAX);

  SET @sql = 'SELECT * FROM ' + @Tabname 
           + ' WHERE ' + QUOTENAME(@colname) + ' = @v';

  EXEC sp_executesql @sql, N'@v VARCHAR(150)', @valuesname;
END
GO

EXEC dbo.queryfunctions N'dbo.education', N'eduChildName', 'Revathi';

何を変えましたか?

  1. オブジェクトを作成/参照するときは、常にdboプレフィックスを使用してください。
  2. テーブル名と列名はNVARCHAR150文字より長くすることができます。誰かが将来追加する可能性のあるテーブルにパラメータを対応させる方がはるかに安全です。
  3. SET NOCOUNT ONネットワークオーバーヘッドおよび潜在的に誤った結果セットをクライアントに送信することに対するガードとして追加されました。
  4. @sql常にである必要がありますNVARCHAR
  5. QUOTENAMEテーブルや列などのエンティティ名を中心に使用して、SQLインジェクションを阻止し、不適切に選択された名前(キーワードなど)から保護します。
  6. 可能な場合は適切なパラメーターを使用します(これもSQLインジェクションを阻止するためだけでなく、文字列パラメーターで区切り文字のあらゆる種類のエスケープを実行する必要がないようにするためです)。
于 2012-07-26T12:44:55.107 に答える
-3

オブジェクト名をパラメータとして渡すのはなぜですか?

文字列値を@valuesnameに渡す場合、コードは次のようになります。

create procedure queryfunctions 
(
@Tabname varchar(150),@colname varchar(150),@valuesname varchar(150) 
)
as 
begin 
declare @sql varchar(4000) 
select @sql='select * from '+@Tabname+' where '+@colname+'='''+@valuesname+'''' 
exec(@sql) 
end 

動的SQLで一重引用符を使用する方法がわかりませんか?これを参照してくださいhttp://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx

于 2012-07-26T12:53:14.883 に答える