2014-10-08 166 views
2

我在.NET應用程序有以下SQL命令:C#SQL參數限制?

sqlCommand.Text = "DECLARE @method NVARCHAR(MAX); 
        SET @method = ' WITH selectRows AS (SELECT *, row=ROW_NUMBER() OVER(ORDER BY(SELECT 1)) FROM [' + @param + ']) SELECT ' + @param_2 + ' FROM selectRows WHERE row BETWEEN 0 AND 30;' 
        EXEC(@method);"; 
sqlCommand.Parameters.AddWithValue("@param", tableName); 
sqlCommand.Parameters.AddWithValue("@param_2", columnString); 

每當「@ PARAM_2」長查詢將不會執行。假設列字符串如下所示:

[class],[partnr],[accessoriesidentifier],[canbelinedup],[certificate],[certificate_ce],[certificate_ul],[certificate_vde],[codeletter],[construction],[craftcooling],[craftelectro],[craftfluid],[crafthydraulic],[craftlubrication],[craftmechanic],[craftpneumatic],[craftprocess],[create],[depth],[depthspacingfront],[depthspacingrear],[description1],[description2],[description3],[discount],[ecabinetmacro],[erpnr],[externaldocument1],[externaldocument2],[externaldocument3],[externalplacement],[functiongroup],[graphicmacro],[groupnumber],[groupsymbolmacro],[height],[heightspacingabove],[heightspacingbelow],[identcode],[identtype],[isaccessory],[lastchange],[lifetime],[macro3d],[maintenance],[manufacturer],[mountinglocation],[mountingspace],[note],[ordernr],[packagingprice1],[packagingprice2],[packagingquantity],[picturefile],[piecetype],[priceunit],[productgroup],[productsubgroup],[producttopgroup],[purchaseprice1],[purchaseprice2],[quantityunit],[reportid],[salesprice1],[salesprice2],[snapheight],[snapheightmiddleoffset],[spare],[stress],[supplier],[terminal],[typenr],[uniqueid],[usage],[wear],[weight],[width],[widthspacingleft],[widthspacingright],[barcount],[bardistance],[bargeometry],[barmountingplatedistance],[bottompaneldepth],[bottompaneldistance],[bottompanelprojectionback],[bottompanelprojectionfront],[bottompanelprojectionleft],[bottompanelprojectionright],[busbarholderpartnr],[busbarholdervariant],[busbarrailpartnr],[busbarrailvariant],[deliverylength],[dooroffsetright],[dooroffsettop],[doorthickness],[doortrabbet],[doortype],[hingeposition],[insertpointoffsetx],[profiledepth],[profiledistance],[profileheight],[rearpaneldistance],[rearpaneldpepth],[rearpanelprojectionbottom],[rearpanelprojectionleft],[rearpanelprojectionright],[rearpanelprojectiontop],[sidepaneldepth],[sidepaneldistance],[sidepanelprojectionback],[sidepanelprojectionbottom],[sidepanelprojectionfront],[sidepanelprojectiontop],[toppaneldistance],[toppaneldpepth],[toppanelprojectionback],[toppanelprojectionfront],[toppanelprojectionleft],[toppanelprojectionright],[vprofiledepth],[vprofilewidth],[wallthickness],[widthbottom],[widthtop],[variant],[adjustrange],[adressrange],[advancecontacts],[airgap],[assemblyspreaded],[awgfrom],[awgtill],[bendingradius],[cabledesignation],[cabledisplayform],[cablelength],[cabletype],[cableweight],[coding],[color],[connection],[connectioncrosssection],[connectiondesignation],[connectionmethod],[contactarrangement],[contacttype],[coppernumber],[creepagedistance],[crosssectionfrom],[crosssectiontill],[currentcsa],[currentiec],[currentul],[degofprotection],[design],[doordepth],[doorheight],[doormountingspace],[doorwidth],[electricalcurrent],[electricalpower],[firmwareversion],[flow],[holdingpower],[innerdiameter],[intrinsicsafety],[material],[norm],[outerdiameter],[paneldepth],[panelheight],[panelmountingspace],[panelwidth],[pincount],[pipeclass],[plcdeviceid],[plcisbuscoupler],[plcisbusdistributor],[plciscpu],[plcispowersupply],[plcobjectdescription],[plctype],[powerdissipation],[pressure],[pressurelevel],[shortcircuitresistant],[standardinvers],[strokelength],[symbolfile],[symbolnr],[technicalcharacteristics],[thread],[triggercurrent],[voltage],[voltagecsa],[voltageiec],[voltagetype],[voltageul],[widthrating],[wirecount],[wirecrosssection],[wirecrosssectionanddiameter],[wirecrosssectionunit],[variant_1],[characteristics],[connectiondescription],[connectiondesignation_1],[description],[functiondefcategory],[functiondefgroup],[functiondefid],[hasled],[hasplugadapter],[idx1],[idx2],[intrinsicsafety_1],[nesteddevicetag],[pos],[safetyrelevant],[symbol],[symbolmacro],[terminalfunction],[terminalnr],[partnr_1],[variant_2],[count],[parentvariant],[pos_1],[22235.0],[22236.0],[22237.0],[22238.0],[22239.0],[22240.0],[22241.0],[22196.1],[22196.2],[22158.1],[22158.2],[22159.1],[22159.2],[22195.1],[22195.2],[22228.1],[22228.2],[22228.3],[22228.4],[22228.5],[22228.6],[22228.7],[22228.8],[22228.9],[22228.10] 

查詢將不會在服務器上執行(SQL Server 2005)。當我刪除10列時,查詢執行時沒有任何問題。我使用sql分析器來查找sql​​ server從我的應用程序收到的任何問題,但沒有發現問題。我很困惑爲什麼它不工作。

我試圖實現的是從數據庫表中取出行列的所有列的結果集。因爲如果我將SELECT @ param_2更改爲SELECT *,我將獲得顯示行號的所有列加和額外列。爲了擺脫這個行號,我想我只是將所有列名發送到查詢的SELECT語句。不過,我現在正在運行上述問題。我希望有人知道一個解決方案,它可以解決上面的問題,也可以知道如何使用比我使用的查詢更好的查詢來獲取排除行號之外的所有列的結果集。

P.s:('失敗')列字符串的大小是3612個字符。 我沒有太多的SQL本身的經驗。所以,如果我犯了愚蠢的錯誤,請原諒。

編輯: 列名取決於用戶,所以他們不能在查詢中硬編碼。

+0

哎呦錯字,把它改爲2005 – WonderTiger 2014-10-08 08:24:22

回答

1

無論你的字符串字面量也不是你傳遞的參數是,自己,nvarchar(max)類型。因此,您對此評論大概有誤string concatenation

如果字符串連接的結果超過了8,000字節的限制,結果會被截斷。但是,如果至少有一個連接的字符串是大值類型,則不會發生截斷。

什麼我可能會做的是改變參數明確是nvarchar(max)

sqlCommand.Parameters.Add("@param_2", SqlDbType.NVarChar,-1).Value = 
    columnString; 

另外,您可以用修復:

SET @method = CONVERT(nvarchar(max), 
' WITH selectRows AS (SELECT *, row=ROW_NUMBER() OVER(ORDER BY(SELECT 1)) FROM [') + ... 
+0

當我告訴該參數是一個nvarchar(max)它的工作原理!謝謝!我很好奇,爲什麼當我不指定大小時它不工作?因爲sql分析器顯示我nvarchar是與列字符串相同的大小。 – WonderTiger 2014-10-08 08:33:08

+0

@WonderTiger - 因爲它只有3612個字符長,所以'AddWithValue'決定將它作爲一個'nchar(3612)'或一個'nvarchar(3612)'(不知道是哪一個)發送。 – 2014-10-08 08:34:06

1

也許這並不直接回答這個問題,但它可能會有所幫助。爲什麼你需要使用dynamioc sql?爲什麼你不能使用:

string sql = @" 
WITH CTE AS 
( 
     SELECT *, 
        row=Row_number() OVER (ORDER BY (SELECT 1)) 
     FROM  dbo.TableName 
SELECT [class],[partnr],[accessoriesidentifier],[canbelinedup],[certificate],[certificate_ce],[certificate_ul],[certificate_vde],[codeletter],[construction],[craftcooling],[craftelectro],[craftfluid],[crafthydraulic],[craftlubrication],[craftmechanic],[craftpneumatic],[craftprocess],[create],[depth],[depthspacingfront],[depthspacingrear],[description1],[description2],[description3],[discount],[ecabinetmacro],[erpnr],[externaldocument1],[externaldocument2],[externaldocument3],[externalplacement],[functiongroup],[graphicmacro],[groupnumber],[groupsymbolmacro],[height],[heightspacingabove],[heightspacingbelow],[identcode],[identtype],[isaccessory],[lastchange],[lifetime],[macro3d],[maintenance],[manufacturer],[mountinglocation],[mountingspace],[note],[ordernr],[packagingprice1],[packagingprice2],[packagingquantity],[picturefile],[piecetype],[priceunit],[productgroup],[productsubgroup],[producttopgroup],[purchaseprice1],[purchaseprice2],[quantityunit],[reportid],[salesprice1],[salesprice2],[snapheight],[snapheightmiddleoffset],[spare],[stress],[supplier],[terminal],[typenr],[uniqueid],[usage],[wear],[weight],[width],[widthspacingleft],[widthspacingright],[barcount],[bardistance],[bargeometry],[barmountingplatedistance],[bottompaneldepth],[bottompaneldistance],[bottompanelprojectionback],[bottompanelprojectionfront],[bottompanelprojectionleft],[bottompanelprojectionright],[busbarholderpartnr],[busbarholdervariant],[busbarrailpartnr],[busbarrailvariant],[deliverylength],[dooroffsetright],[dooroffsettop],[doorthickness],[doortrabbet],[doortype],[hingeposition],[insertpointoffsetx],[profiledepth],[profiledistance],[profileheight],[rearpaneldistance],[rearpaneldpepth],[rearpanelprojectionbottom],[rearpanelprojectionleft],[rearpanelprojectionright],[rearpanelprojectiontop],[sidepaneldepth],[sidepaneldistance],[sidepanelprojectionback],[sidepanelprojectionbottom],[sidepanelprojectionfront],[sidepanelprojectiontop],[toppaneldistance],[toppaneldpepth],[toppanelprojectionback],[toppanelprojectionfront],[toppanelprojectionleft],[toppanelprojectionright],[vprofiledepth],[vprofilewidth],[wallthickness],[widthbottom],[widthtop],[variant],[adjustrange],[adressrange],[advancecontacts],[airgap],[assemblyspreaded],[awgfrom],[awgtill],[bendingradius],[cabledesignation],[cabledisplayform],[cablelength],[cabletype],[cableweight],[coding],[color],[connection],[connectioncrosssection],[connectiondesignation],[connectionmethod],[contactarrangement],[contacttype],[coppernumber],[creepagedistance],[crosssectionfrom],[crosssectiontill],[currentcsa],[currentiec],[currentul],[degofprotection],[design],[doordepth],[doorheight],[doormountingspace],[doorwidth],[electricalcurrent],[electricalpower],[firmwareversion],[flow],[holdingpower],[innerdiameter],[intrinsicsafety],[material],[norm],[outerdiameter],[paneldepth],[panelheight],[panelmountingspace],[panelwidth],[pincount],[pipeclass],[plcdeviceid],[plcisbuscoupler],[plcisbusdistributor],[plciscpu],[plcispowersupply],[plcobjectdescription],[plctype],[powerdissipation],[pressure],[pressurelevel],[shortcircuitresistant],[standardinvers],[strokelength],[symbolfile],[symbolnr],[technicalcharacteristics],[thread],[triggercurrent],[voltage],[voltagecsa],[voltageiec],[voltagetype],[voltageul],[widthrating],[wirecount],[wirecrosssection],[wirecrosssectionanddiameter],[wirecrosssectionunit],[variant_1],[characteristics],[connectiondescription],[connectiondesignation_1],[description],[functiondefcategory],[functiondefgroup],[functiondefid],[hasled],[hasplugadapter],[idx1],[idx2],[intrinsicsafety_1],[nesteddevicetag],[pos],[safetyrelevant],[symbol],[symbolmacro],[terminalfunction],[terminalnr],[partnr_1],[variant_2],[count],[parentvariant],[pos_1],[22235.0],[22236.0],[22237.0],[22238.0],[22239.0],[22240.0],[22241.0],[22196.1],[22196.2],[22158.1],[22158.2],[22159.1],[22159.2],[22195.1],[22195.2],[22228.1],[22228.2],[22228.3],[22228.4],[22228.5],[22228.6],[22228.7],[22228.8],[22228.9],[22228.10] 
FROM CTE 
WHERE row BETWEEN @StartRow AND @EndRow;"; 

using(var sqlCommand = new SqlCommand(sql, con)) 
{ 
    sqlCommand.Parameters.Add("@StartRow", SqlDbType.int).Value = 1; 
    sqlCommand.Parameters.Add("@EndRow", SqlDbType.int).Value = 30; 
    // ... 
} 

由於列名由用戶指定的,你不能沒有動態SQL將其添加爲參數。但是你知道所有有效的列名,所以你可以檢查是否全部有效。如果您不知道表格的所有列,請查看here並使用reader.GetSchemaTable加載應用程序啓動時的所有列。

然後,你可以簡單地把它添加到SQL:

string sql = @" 
WITH CTE AS 
( 
     SELECT *, 
        row=Row_number() OVER (ORDER BY (SELECT 1)) 
     FROM  dbo.TableName 
SELECT {0} 
FROM CTE 
WHERE row BETWEEN @StartRow AND @EndRow;"; 

sql = string.Format(sql, string.Join(",", columnList)); 
+0

列名根據用戶而改變,所以它們不能在查詢中被硬編碼。至少我是這麼想的,也許我錯了? – WonderTiger 2014-10-08 08:25:49

+0

@WonderTiger:表格也必須是動態的,或者你是否在編譯時知道它? – 2014-10-08 08:28:33

+0

是的,它是動態的。這張桌子是一種讓excel,csv,tekst等相互匹配的臨時表。 – WonderTiger 2014-10-08 08:31:01