2012-08-29 165 views
2

我想從一個字符串執行一個SQL查詢,我用變量生成。該SP產生一個選擇查詢,當我手動執行這個查詢它的工作原理,但是當它在SP有像SQL查詢字符串

消息911,級別16,狀態4,過程sp_Products_Select錯誤,第26行
數據庫「 SELECT *(選擇部分與部分,其中SectionID = 產品不存在。請確保名稱輸入正確 。

從SP生成的查詢

SELECT 
    *, 
    (Select Section 
    From Sections 
    Where SectionID = dbo.Products.SectionID) as Section, 
    (Select Category 
    From Categories 
    Where CategoryID = Products.CategoryID) as Category 
FROM 
    Products 
WHERE 
    1 = 1AND (Status = 1 OR Status = 0) 

我的SP是,

ALTER PROC [dbo].[sp_Products_Select] 
    @ProductID int, 
    @Status int, 
    @CategoryID int, 
    @SectionID int 
AS 

DECLARE @SQL varchar(500) 
SET @SQL ='SELECT *,(Select Section From Sections Where SectionID = Products.SectionID) as Section,(Select Category From Categories Where CategoryID = Products.CategoryID) as Category FROM Products WHERE 1 = 1'; 
IF @ProductID <> '0' BEGIN 
    SET @SQL += 'AND ProductID = @ProductID'; 
END 
IF @Status <> 0 BEGIN 
    SET @SQL += 'AND Status = @Status'; 
END ELSE BEGIN 
    SET @SQL += 'AND (Status = 1 OR Status = 0)'; 
END 
IF @CategoryID <> '0' BEGIN 
    SET @SQL += 'AND CategoryID = @CategoryID'; 
END 
IF @SectionID <> '0' BEGIN 
    SET @SQL += 'AND SectionID = @SectionID'; 
END 

EXEC @SQL 

如何從SP正確執行這個查詢?

+0

只需照顧你的'AND CategoryID = @CategoryID'部分。 –

回答

3

你在你的 WHERE條款缺少空間:

WHERE 
    1 = 1AND (Status = 1 OR Status = 0) 

必須是:

WHERE 
    1 = 1 AND (Status = 1 OR Status = 0) 
     * 
     * space here is absolutely essential! 

所以,你需要更改構建了T-SQL語句的存儲過程的代碼把至少 一個空間之間 1 = 1AND ....

這不是問題,因爲馬丁·史密斯發現....

更新:好 - 這樣的空間似乎並不終究需要.....

:嘗試使用

EXEC (@SQL) 

我相信你需要在執行時,它把你的SQL語句轉換成支架。

+3

'SELECT 1 WHERE 1 = 1AND 2 = 2'實際上解析得很好。 'EXEC(...)'後面的問題是括號括起來' –

+0

謝謝,我試過但仍然有同樣的錯誤 –

+0

@MartinSmith:嗯....你說得對....我可以**發誓* *在我的日子裏,我的問題與基本相同的結構('WHERE 1 = 1AND ....')有關:-) –

0

你需要一個空間後,1 = 1

'SELECT *,(Select Section From Sections Where SectionID = Products.SectionID) as Section,(Select Category From Categories Where CategoryID = Products.CategoryID) as Category FROM Products WHERE 1 = 1 '; 
1

嘗試簡化您的查詢,

SELECT a.*, b.Section, c.Section 
FROM Products a 
      INNER JOIN Sections b 
       ON a.SectionID = a.SectionID 
      INNER JOIN Categories c 
       ON a.SectionID = c.Category 

,並在您SET @SQL語法,你需要add extra space他們。

SET @SQL += ' AND ProductID = @ProductID'; 
      ^here 
1

編輯:

所以EXEC(..)不會解決你所有的問題!

我想你甚至需要爲動態查詢聲明@ProductID和@CategoryID以及其他參數,如果你想在裏面運行它們的話。

EXEC啓動另一個作用域,就像另一個StoredProcedure調用一樣。在其他範圍內,您的@variables將不可用。您可以在臨時表上引用,但不能在內存表或變量上引用。

我會說,改變像那些行:

SET @SQL += 'AND ProductID = @ProductID' 

爲了這樣的事情(這個人是有點難看BTW):

SET @SQL += 'AND ProductID = ' + CAST(@ProductID as varchar(20)) 

OR

乘坐看看sq_executesql,用這個你可以定義參數和參數值。如果您通過大量臨時查詢來檢查SQL事件探查器,則引擎也會執行相同的操作。只需使用sp_executesql和參數將輸入作爲動態sql運行即可。