【问题标题】:C# Using sql parameters which now won't workC# 使用现在不起作用的 sql 参数
【发布时间】:2015-11-17 23:59:52
【问题描述】:

嘿,我正在为我的应用程序使用参数化查询,它工作得很好,但现在(我不知道为什么)它们不再被值替换...

因此,它不会运行"SELECT [TABLE_NAME] FROM [MyDefinetelyExistingDatabase]"; 之类的东西,而是尝试执行"SELECT [TABLE_NAME] FROM [@targetDatabase]";,这当然会失败。

 var dataBaseToGetTablesFrom = "MyDefinetelyExistingDatabase";
 var results = new List<string>();

        const string query = @"SELECT
                                    [TABLE_NAME] AS tableName
                                FROM 
                                    [@targetDatabase].[INFORMATION_SCHEMA].[TABLES] ;";
        
        using (var context = new ConnectionHandler(true))
        {
            if (context.Connection.State != ConnectionState.Open)
                throw new ConnectionFailedException(context.Connection.State);

            using (var command = new SqlCommand(query, context.Connection))
            {
                command.Parameters.AddWithValue("@targetDatabase", dataBaseToGetTablesFrom);

                using (var reader = command.ExecuteReader())
                {
                    if (!reader.HasRows)
                        return results.ToArray();

                    while (reader.Read())
                        results.Add(reader.GetString(0));
                }
            }
        }
        return results.ToArray();

我现在尝试了不同的格式和东西来添加参数,但结果相同...... 我不想通过string.Format 直接将值插入到查询中来做到这一点,例如,但我想要这些参数(它们在代码中的不同位置正常工作(???)但不是我想要的。

事实上,我需要在每个语句中使用参数,并且必须能够通过调用它们来处理不同的数据库,例如 [DB].[Table-Schema].[Table]

[编辑]

嘿,伙计们,几天前就发现了这个问题,并想与你们分享。 据我所知,我的整体问题是尝试替换数据库名和/或在其他一些示例中,表名也是如此。 所以这行不通,这对我来说很有意义,因为如果服务器甚至不知道它应该在哪个表上工作并且因此对结构等一无所知,它就无法准备执行语句。

所以我改变了我的陈述以适应我的新知识,它就像一个魅力一样发挥了预期的作用。

【问题讨论】:

  • @lad2025 你不能在 USE 语句中使用 variableGO 不是 t-sql ,它只能在 SSMS 中作为 batch separator 使用。
  • 不是您问题的答案,但您应该阅读此内容。 blogs.msmvps.com/jcoehoorn/blog/2014/05/12/…
  • @M.Ali 是的,所以我们一如既往地回到动态 SQL :)

标签: c# mysql sql-server parameters


【解决方案1】:

我不知道ConnectionHandler 是什么,但如果这是您自己的代码,您可以使用SqlConnectionStringBuilder 来实现它,这将允许您使用变量来分配InitialCatalog,而不是将数据库名称放入查询。这比需要仔细清理的动态 sql 更可取。

【讨论】:

  • 这意味着打开一个新连接来查询每个数据库,对我来说这对于一个相当简单的任务来说似乎有点矫枉过正:S
  • @M.Ali - 我不同意,为每个查询打开一个新连接是执行 ADO.NET 查询的首选和推荐方式。 Sql Server 将处理连接池,因此从您的代码中抽象出实际创建新连接的昂贵行为。简而言之,我同意 Crowcoder 的观点,它将消除检查数据库名称参数的需要,并且如果数据库不存在、拼写错误、没有访问权限等,它还可以帮助您生成更好的错误消息.
  • @M.Ali 连接池保持连接的高效使用。
【解决方案2】:

您需要动态 sql 来处理类似.....

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = N' SELECT [TABLE_NAME] AS tableName '
         + N' FROM ' + QUOTENAME(@targetDatabase) + N'.[INFORMATION_SCHEMA].[TABLES]'

Exec sp_executesql @Sql 

【讨论】:

  • 嗨,谢谢回复 一个简单的查询似乎需要做很多工作,执行一个参数一定更容易
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
相关资源
最近更新 更多