2017-06-19 77 views
0

我想創建過程並出現以下錯誤;存儲過程中的SQL變量表名稱錯誤

將nvarchar值'select ID轉換爲#a from @table時轉換失敗其中yil ='爲數據類型int。

怎樣才能寫出正確的程序?我的程序;

@tablo nvarchar(100), 
@kayit nvarchar(50), 
@inceleme nvarchar(50), 
@icevap nvarchar(50), 
@tespit nvarchar(MAX), 
@scevap nvarchar(MAX), 
@aksiyon nvarchar(50), 
@mutalaa nvarchar(MAX), 
@tamamlanma nvarchar(100), 
@not nvarchar(MAX), 
@izleme nvarchar(50), 
@kaydeden nvarchar(50), 
@idd int, 
@kullanici nvarchar(50), 
@yil int, 
@donem int 

as 

DECLARE @sql as varchar(max) 
SET @sql = 'select ID into #a from' + @tablo+ 
' Where yil='[email protected]+' and donem='[email protected]+' and (ilkkaydeden is 
null or ilkkaydeden='') and (kull='[email protected]+' or 
kull1='[email protected]+' or kull2='[email protected]+')' 
EXEC(@sql) 
+1

請添加處理您正在使用的變量的代碼。 @yil是什麼數據類型?它是int嗎?如果是這樣,您可能需要將其轉換爲nvarchar。即'yil ='+ CAST(@yil as nvarchar)'。此外,您可以在這裏失去了一個'和':'+ @ + YIL「donem =' – SchmitzIT

回答

-2

更新(評論後):只投那麼INT變量VARCHAR,以便串聯工作

DECLARE @tablo NVARCHAR(100) 
    , @kayit NVARCHAR(50) 
    , @inceleme NVARCHAR(50) 
    , @icevap NVARCHAR(50) 
    , @tespit NVARCHAR(MAX) 
    , @scevap NVARCHAR(MAX) 
    , @aksiyon NVARCHAR(50) 
    , @mutalaa NVARCHAR(MAX) 
    , @tamamlanma NVARCHAR(100) 
    , @not NVARCHAR(MAX) 
    , @izleme NVARCHAR(50) 
    , @kaydeden NVARCHAR(50) 
    , @idd INT 
    , @kullanici NVARCHAR(50) 
    , @yil INT 
    , @donem INT 
DECLARE @sql AS VARCHAR(max) 

SET @sql = 'select ID into #a from' + @tablo + ' Where yil=' + cast(@yil as varchar) + ' and donem=' + cast(@donem as varchar) + ' and (ilkkaydeden is 
null or ilkkaydeden='') and (kull=' + @kullanici + ' or 
kull1=' + @kullanici + ' or kull2=' + @kullanici + ')' 

EXEC (@sql) 
+0

雖然這可以回答這個問題,一些意見和/或解釋將是很好。這也會幫助其他用戶。 – VDWWD

+0

@VDWWD我不擅長解釋事物 – lostmylogin

+0

你肯定可以解釋自己的代碼? – jAC

0

你有兩個變量作爲整數@yil & @donem和你如果不先將它們轉換爲varcharnvarchar,則不能連接它們。

使用下面的代碼: -

DECLARE @sql as varchar(max) 
SET @sql = 'select ID into #a from' + @tablo+ 
' Where yil='+convert(nvarchar(20),@yil)+' and donem='+convert(nvarchar(20),@donem)+' and (ilkkaydeden is 
null or ilkkaydeden='') and (kull='[email protected]+' or 
kull1='[email protected]+' or kull2='[email protected]+')' 
EXEC(@sql) 
0

對於INT值,聲明爲INT,然後創建動態SQL時,使用

CONVERT(VARCHAR, @var) 

對於char值,添加額外的引號是這樣的:

'...var='''[email protected]_var+''' more text..' 
0

您不應該像現在這樣編寫存儲過程,它們很容易受到SQL注入攻擊。使用參數化查詢重寫他們,他們將會很安全:

CREATE PROCEDURE test 
    @tablo NVARCHAR(100) 
    , @kayit NVARCHAR(50) 
    , @inceleme NVARCHAR(50) 
    , @icevap NVARCHAR(50) 
    , @tespit NVARCHAR(MAX) 
    , @scevap NVARCHAR(MAX) 
    , @aksiyon NVARCHAR(50) 
    , @mutalaa NVARCHAR(MAX) 
    , @tamamlanma NVARCHAR(100) 
    , @not NVARCHAR(MAX) 
    , @izleme NVARCHAR(50) 
    , @kaydeden NVARCHAR(50) 
    , @idd INT 
    , @kullanici NVARCHAR(50) 
    , @yil INT 
    , @donem INT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 

    SET @tablo = ( SELECT FORMATMESSAGE('%s.%s', QUOTENAME(SCHEMA_NAME(O.schema_id)), QUOTENAME(O.name)) 
        FROM sys.objects AS O 
        WHERE O.object_id = OBJECT_ID(@tablo, 'U')); 

    SET @sql = N' 
     SELECT ID 
     INTO #a 
     FROM ' + @tablo + ' 
     WHERE yil = @yil 
     AND donem = @donem 
     AND (ilkkaydeden IS NULL OR ilkkaydeden = '') 
     AND @kullanici IN (kull, kull1, kull2);'; 

    EXEC sys.sp_executesql @sql, N'@yil INT, @donem INT, @kullanici NVARCHAR(50)', @yil, @donem, @kullanici; 
END; 

如果你必須動態插入表名,它包裝成QUOTENAME()功能,它會包住可變進方括號,並使其有效的對象名。

在這種情況下,我甚至是否@tablo表存在併爲其分配一個適當的值,這是模式和表的結構和使用安全。