【问题标题】:Can I get the query that was executed from the SqlDataSource?我可以获取从 SqlDataSource 执行的查询吗?
【发布时间】:2009-03-27 13:18:19
【问题描述】:

我的 SqlDataSource 上有我的 SelectCommand 的 sql 查询。如下所示:

SELECT * FROM Books WHERE BookID = @BookID

TextBox 使用 Asp:ControlParameter 提供 @BookID 参数。

当我在单步执行代码时查看 SelectCommand 时,我看到:

SELECT * FROM Books WHERE BookID = @BookID

我真正想看到的是,如果人在TextBox中输入3,我想看到

SELECT * FROM Books WHERE BookID = 3

我不知道如何访问上述内容?

【问题讨论】:

  • 如果 SqlDataSource 有任何价值,它会将您的文本框值作为 @BookId 参数传递,以帮助避免 SQL 注入攻击。正如 irperez 在下面所说,SQL Profiler 是完成这项工作的工具。

标签: c# asp.net sqldatasource


【解决方案1】:

查看实际查询的一种方法是使用 SQL Profiler。

【讨论】:

  • SQL Profiler 仍将同时显示查询和参数,您不会看到完整的详细查询
  • 我不同意。我使用 Profiler 查看传递了哪些查询以查看发生了什么,它确实吐出了详细的查询。
  • 我知道使用 Linq 您可以在 IDE 中看到实际的查询,但不确定使用 sqldatasource。除非您连接到 MS 源服务器,否则无需进入代码即可查看。
【解决方案2】:

查询永远不会被执行为

SELECT * FROM Books WHERE BookID = 3

实际上是带参数的参数化查询。

您可以使用相关参数对查询进行“查找/替换”以查看它的外观。

【讨论】:

    【解决方案3】:

    (此答案假定使用 SqlClient 实现。)

    不,你看不到执行的 sql 代码。 SqlCommand 类调用 sp_execute(具体实现请参见 SqlCommand.BuildExecute 方法),它将查询与参数分开。您需要使用 Sql Profiler 来查看执行的确切查询。

    您可以使用提供的 DbCommand(来自 Selecting 事件)来解析您的 CommandText 并将参数替换为它们的实际值。这需要一些逻辑来进行转义,而且它不会是 Sql Server 执行的确切查询。

    【讨论】:

      【解决方案4】:
      Public Function GenSQLCmd(ByVal InSqlCmd As String, ByVal p As Data.Common.DbParameterCollection) As String
          For Each x As Data.Common.DbParameter In p
              InSqlCmd = Replace(InSqlCmd, x.ParameterName, x.Value.ToString)
          Next
          Return InSqlCmd
      End Function
      

      【讨论】:

        【解决方案5】:

        我猜你将无法像你希望的那样看到 select 语句,因为参数在语句中没有被替换为值 3,而是像你将它写到 sql server 一样发送(使用参数)。

        这实际上很好,因为它可以防止有人在你的文本框中注入一些恶意的 sql 代码,例如。

        无论如何,你不能用这个来检索传递给参数的值吗:

        cmd.Parameters(0).Value

        你的 SqlCommand 在哪里 cmd?

        【讨论】:

          【解决方案6】:

          这是亚当答案的 C# 版本

          public string GenSQLCmd(string InSqlCmd, System.Data.Common.DbParameterCollection p) {
              foreach (System.Data.Common.DbParameter x in p) {
                  InSqlCmd = InSqlCmd.Replace(x.ParameterName, "'" + x.Value.ToString() + "'");
              }
              return InSqlCmd;
          }
          

          用法:

          string DebugQuery = GenSQLCmd(cmd.CommandText, cmd.Parameters); //cmd is a SqlCommand instance
          

          【讨论】:

            【解决方案7】:

            是的,您可以查看该信息,但您需要为此进行一些编码。

            1. 创建一个名为 ToSqlStatement 的扩展方法
            
                public static class SqlExtensions
                {
                    public static string ToSqlStatement(this IDbCommand cmd)
                    {
                        var keyValue = new List<string>();
                        foreach (SqlParameter param in cmd.Parameters)
                        {
                            var value = param.Value == null ? "NULL" : "'" + param.Value + "'";
                            keyValue.Add($"{param.ParameterName}={value}");
                        }
                        return $"{(cmd.CommandType == CommandType.StoredProcedure ? "exec " : string.Empty)}{cmd.CommandText} {string.Join(", ", keyValue)}";
                    }
                }
            
            
            1. OnSelecting 事件处理程序添加到页面上的 SqlDataSource 控件
            2. 在你的代码后面
            
                protected void sqlDataSource_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
                {
                    MyLogger.WriteLine(e.Command.ToSqlStatement());
                }
            
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-10-06
              • 1970-01-01
              • 2010-11-15
              • 2010-12-18
              • 2011-05-13
              • 1970-01-01
              • 2010-11-15
              • 2011-03-03
              相关资源
              最近更新 更多