C# T-SQL 语句包含“with(nolock)”错误

Posted

技术标签:

【中文标题】C# T-SQL 语句包含“with(nolock)”错误【英文标题】:C# T-SQL statement includes "with(nolock)" error 【发布时间】:2011-12-28 21:48:00 【问题描述】:

短:

我的 C# 代码中的 SQL 语句不起作用。 with(nolock) 正在破解密码。

详细说明:

以下是我的错误和出现错误的代码。该代码应该连接到我的 SQL Server 数据库(连接代码工作正常)然后运行查询。此查询将获取所有具有“blah”uri 的事件的 IP 地址。问题似乎是我需要使用的with(nolock) 命令。我必须使用它,因为它是所有 T-SQL 查询的组标准。

我用谷歌搜索了一段时间,但似乎没有什么适合我的问题,而且我发现的修复方法还没有奏效。对我的代码或链接的任何帮助将不胜感激。

错误:

System.Data.SqlClient.SqlException 被捕获 Message=Incorrect 关键字'with'附近的语法。如果这个语句是公用表 表达式、xmlnamespaces 子句或更改跟踪上下文 子句,前面的语句必须以分号结束。 源=.Net SqlClient 数据提供程序错误代码=-2146232060 类=15 LineNumber=1 Number=319 Procedure="" Server= State=1

代码:

try

   //create sql reader to display data
   SqlDataReader myReader = null;

   //create string to enter data into database
   string insString = @"select c_ip from @dates with(nolock) where cs_uri like 'blah'";
   SqlCommand myCommand = new SqlCommand(insString, DbConnection);

   //populate and sanitize parameters
   myCommand.Parameters.Add("@dates", SqlDbType.VarChar, 100);
   myCommand.Parameters["@dates"].Value = currentdate;

   //execute the command
   myReader = myCommand.ExecuteReader();

   //read all results and print them to output
   while (myReader.Read())
   
      //get IPs              
      String ipmix = myReader["c_ip"].ToString();
      mainIPs.Add(ipmix);
   

catch (Exception e)

   Console.WriteLine("The query connection to the datebase has timed out.\n");
   Console.WriteLine(e.ToString());
   Console.ReadLine();

解决方案:

更改代码:

//create string to enter data into database
string insString = @"select c_ip from @dates with(nolock) where cs_uri like 'blah'";

到:

//create string to enter data into database
string insString = @"select c_ip from " + currentdate + " with(nolock) where cs_uri like '%blah'";

【问题讨论】:

不是with,而是@dates 感谢您输入 StingyJack!有什么建议吗? @toosweetnitemare:您知道并正在处理 WITH NOLOCK 会导致您错过已经提交的行吗? @Anders UP:是的,我知道。正在访问的 DB 不断被写入,我们更关心正在完成的写入,然后丢失一些已提交的行。谢谢你提出这个细节。我相信这个线程的未来读者会喜欢它! :D 【参考方案1】:

它不是 WITH,它是 @dates 变量。您基本上是在创建语句....

select c_ip from '12/28/2011 15:35:22.997' with(nolock) where cs_uri like 'blah'

这没有任何意义。

此外,您给用户的异常消息并不正确。错误可能是任何数量的东西(比如“不正确的语法”),但你告诉他们这是一个超时问题。

根据您的评论,您应该将查询文本更改为...

string insString = @"select c_ip from " + currentdate + " with(nolock) where cs_uri = 'blah'";

当您在代码中生成 currentdate 值而不是从任何用户输入时,您不会面临 SQL 注入的风险。取出like并用equals替换它也会提高查询性能。另外,完全删除参数。

【讨论】:

值得澄清的是,即使@dates 包含有效的对象名称,它仍然无法工作。表名不能参数化。 我正在使用一种方法来获取日期并对其进行格式化 //current date DateTime dt = DateTime.Now; //日期 = 12/28/2011 12:00:00 AM String datebreaker = dt.ToString(); String[] notime = datebreaker.Split(' '); String[] datesplit = notime[0].Split('/');字符串年 = 日期分割[2].Substring(日期分割[2].长度 - 2);字符串月份 = 日期拆分 [0];字符串天 = 日期拆分 [1]; //View_v2_111226 currentdate = "View_v2_" + 年 + 月 + 日; 你没有抓住重点。参数通常用于 WHERE 子句。您不能在 FROM 子句中为表名使用参数。 感谢您的澄清。那么我将如何插入表名呢?每个表都是新的一天,每次我运行这个应用程序时表名都会改变。【参考方案2】:

在构建选择语句时去掉参数代码并添加表名

string insString = @"select c_ip from " + currentdate + " with(nolock) where cs_uri like 'blah'";

【讨论】:

这正是我想要的。谢谢!我会尽快为您提供解决方案的功劳。【参考方案3】:

您已要求它从名为 @Dates 的表中选择记录。 (这是日期参数) - 将评估为

select 'c_ip from 28-12-2011...'

你可能想要类似的东西

"select c_ip from logtable with(nolock) where cs_uri like 'blah' and log_date=@dates"

不要忘记,如果您使用的是 DATETIME 字段,日期是由日期和时间组成的,因此您可能还需要构建一个从 00:00:0023:59:59 的相关日期范围(或使用currentdate+1 捕捉午夜重叠)

这给了你

select c_ip from logtable with(nolock) where (cs_uri like '%blah%') and (log_date between @startdate and @enddate)

【讨论】:

以上是关于C# T-SQL 语句包含“with(nolock)”错误的主要内容,如果未能解决你的问题,请参考以下文章

WITH (NOLOCK)

WITH (NOLOCK)

sqlserver with(nolock)

使用 WITH (NOLOCK) 和事务

使用 WITH(NOLOCK) 提高性能

sql中nolock的语法