【问题标题】:Dynamic seek for a string sql and replace in C#在 C# 中动态查找字符串 sql 并替换
【发布时间】:2015-05-21 14:48:59
【问题描述】:

我使用 ADO DataReader 从 sql server 获取行。由于 DataReader 没有记录数,我需要自己获取记录数。因此,在我的情况下,我想将传递给动态类的原始 sql 语句放在子查询中。

例子

SELECT 
      id, 
      title, 
      value 
FROM table 
WHERE id = 1234 
ORDER BY title

应该是

SELECT COUNT(*) 
   FROM (
         SELECT id, 
               title,
               value 
        FROM table 
        WHERE id = 1234 
        ORDER BY title)t

在这种情况下,我们需要修改 SQL 语句,因为语法要求添加 TOP 100 PERCENT 才能正常工作:

SELECT COUNT(*) 
FROM (SELECT TOP 100 PERCENT id, 
                     title, 
                     value 
              FROM table 
              WHERE id = 1234 
              ORDER BY title)t

所以我这样做了:

int fromIndex = this.SQL.IndexOf("SELECT", 
                     StringComparison.CurrentCultureIgnoreCase);
String countSql = "SELECT TOP 100 PERCENT" + 
                   this.SQL.Substring(fromIndex + 6);
countSql = "SELECT COUNT(*) FROM (" + countSql + ")t";

但是如果原始语句已经有一个像这样的 TOP 子句怎么办

SELECT TOP 5 id, 
             title, 
             value 
 FROM table 
 WHERE id = 1234 
 ORDER BY title

甚至更糟

SELECT   TOP   5  
               id, 
               title, 
               value 
     FROM table 
     WHERE id = 1234 
     ORDER BY title

所以我的代码需要处理这个。

顺便说一句:如果有人有更好的方法来从 任何 SQL 语句中计算记录,那么这个答案也是受欢迎的!

编辑 澄清我的问题。 链接How to get number of rows using SqlDataReader in C# 解释了如何做到这一点。我读了那个。我的问题是如何处理传入的SQL语句添加TOP 100 PERCENT子句。

【问题讨论】:

  • 在第一个select之后添加select @@rowcount,您可以.NextResult阅读它
  • 我试过这个答案。 => 之前运行专门的 SELECT COUNT(*) 正是我试图做的,因为 sql 语句是动态的,所以我必须处理这个。 @@rowcount 在多查询/多用户系统中没有给我确切的计数...

标签: c# replace datareader


【解决方案1】:

澄清一下:查询是动态传入的吗?然后你想知道它读取了多少行?我相信正如一条评论所暗示的那样;您可以将“select @@rowcount”添加到传入查询的末尾;然后回到 C# 中,使用 .NextResult 从查询结果跳转到您的行计数结果。

【讨论】:

  • 不管有多少用户触发了多少并行语句,@@rowcount 表示 sql 语句中的数字是否 100% 安全?
  • 我相信是这样;它应该只为您的默认事务获取@@rowcount;发生的任何其他事情都应该无关紧要。
【解决方案2】:

DataReader 可能没有行数,但您可以在将结果集解析到数据模型时调用Read() 来推断它。

此外,您的代码容易受到 SQL 注入攻击。您应该使用SqlCommand 并为您的动态值参数添加SqlParameter 对象来代替字符串连接。

这是使用Read()SqlCommand 类的基本示例:MSDN - SqlDataReader.Read

【讨论】:

  • 代码不易受到攻击,因为传递的 sql 语句已经使用您提到的方法设置。 this.SQL 只是内部使用。只是计数也不起作用,因为我原来的 SQL 语句持有例如100 万条记录,但我只获取前 10 行。
猜你喜欢
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多