2014-10-08 163 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