2009-09-21 7 views
0

J'ai une requête dynamique qui se lit comme celui-ciSQL Server 2008 problème de requête dynamique

Alter PROCEDURE dbo.mySP 
    -- Add the parameters for the stored procedure here 
    (
     @DBName varchar(50), 
     @tblName varchar(50) 

    ) 

AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
declare @string as varchar(50) 
declare @string1 as varchar(50) 

set @string1 = '[' + @DBName + ']' + '.[dbo].' + '[' + @tblName + ']' 

set @string = 'select * from ' + @string1 

exec @string 

FIN

J'appelle comme ça

dbo.mySP 'dbtest1','tblTest' 

Et je ressentais une erreur

"Msg 203, Level 16, State 2, Procedure mySP, Line 27 
The name 'select * from [dbtest1].[dbo].[tblTest]' is not a valid identifier." 

Qu'est-ce que wr ong? et Comment surmonter?

Merci à l'avance

+1

Je espère vous êtes en train de vérifier l'injection SQL quelque part ... – GilaMonster

+1

Je frémis de penser que quelqu'un pourrait même envisager d'écrire un sp comme ça. S'il vous plaît lire: http://www.sommarskog.se/dynamic_sql.html – HLGEM

Répondre

5

Il pense que le contenu de @string se réfèrent à un nom de procédure stockée. Vous devez mettre

EXEC (@string) 

ou mieux utiliser la procédure stockée sp_executesql

Vous devez également mettre en place un code de garde pour vérifier que les valeurs que vous transmettez dans les noms des tables et des bases de données réelles. Vous pouvez interroger les vues dans INFORMATION_SCHEMA pour valider l'entrée.

Vous pouvez lire plus sur safer dynamic SQL sur mon blog.

4

Changer

exec @string 

Pour

exec(@string) 

Voici un SP de travail que je viens de tester:

CREATE PROCEDURE [dbo].[test] 
    @DBName varchar(50), 
    @tblName varchar(50) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @string AS VARCHAR(50) 
    DECLARE @string1 AS VARCHAR(50) 

    SET @string1 = '[' + @DBName + '].[dbo].[' + @tblName + ']' 
    SET @string = 'select * from ' + @string1 

    EXEC(@string) 
END 
1

si vous utilisez EXEC comme:

EXEC @String 

il tente d'exécuter une procédure avec le nom contenu dans la variable @String. essayer:

create procedure TestProc 
as 
print 'you called TestProc!' 
go 

declare @string varchar(20) 
set @string='TestProc' 

exec @string 

si vous utilisez EXEC comme:

EXEC (@Query) 

vous exécutez le SQL au sein de la variable @Query, essayer:

DECLARE @Query varchar(50) 
set @Query='Print ''just ran it!''' 

EXEC (@Query) 
0
ALTER PROCEDURE test_sp 
    -- Add the parameters for the stored procedure here 
    (
     @DBName varchar(50), 
     @tblName varchar(50) 

    ) 

AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON 

-- Insert statements for procedure here 
declare @string as varchar(100) 
declare @string1 as varchar(50) 

set @string1 = '[' + @DBName + ']' + '.[dbo].' + '[' + @tblName + ']' 
Print @string1 
set @string = 'select * from' + @string1  
Print @string 
exec (@string) 
SET NOCOUNT OFF 
END 
+0

Qu'avez-vous changé? Et pourquoi cela répond-il à la question? – yhw42