【问题标题】:Issue using .sql command in resource file在资源文件中使用 .sql 命令时出现问题
【发布时间】:2013-05-29 20:31:02
【问题描述】:

我试图将我的 sql 语句存储在资源文件夹中的 .sql 文件中,

我需要将 2 个值传递给 sql 命令,但我很难做到这一点

我的sql如下:

SELECT * FROM claim_header WHERE @columnname = @testcase;

我的班级称它为:

class DataValidation
{
    public string testCase { get; set; }
    public string elementName { get; set; }
    public string fileDestination = ConfigurationSettings.AppSettings["ValidationReportDestination"];
    public List<string> testCasesList = new List<string>();

    public void PrintValidationResults()
    {
        int counter = 0;
        SqlConnection sqlConnection = new SqlConnection(constring);
        string sqlConnectionStringPassed = "select * from claim_header";
        string sqlConnectionStringFailed = "select * from dbo.[SSIS Exception Info] where data_entity_name like '%CLAIM%' and package_name like '%Extract%' order by 1 desc;";
        SqlDataReader myReaderPassed, myReaderFailed = null;
        SqlCommand sqlCommandPassed = new SqlCommand(sqlConnectionStringPassed, sqlConnection);
        SqlCommand sqlCommandFailed = new SqlCommand(sqlConnectionStringFailed, sqlConnection);

        string sqlPass = EmbeddedResource.GetString("PassQuery.sql");
        SqlCommand cmd = new SqlCommand(sqlPass,sqlConnection);

        cmd.Parameters.AddWithValue("@testcase", "'" + testCasesList[counter] + "'");
        cmd.Parameters.AddWithValue("@columnname", elementName);

        try
        {
            sqlConnection.Open();
            myReaderPassed = sqlCommandPassed.ExecuteReader();
            myReaderFailed = sqlCommandFailed.ExecuteReader();
            object query = cmd.ExecuteScalar();
            string test = cmd.CommandText;

            //Print Passed Results
            Directory.CreateDirectory(fileDestination);
            using (StreamWriter resultWriter = new StreamWriter((fileDestination + elementName + ".txt"), true))
            {
                    while (myReaderPassed.Read())
                    {
                        foreach (string testCase in testCasesList)
                        {
                            if (myReaderPassed[elementName].ToString() == testCase)
                            {
                                {
                                    resultWriter.WriteLine("Field: " + elementName.ToString());
                                    resultWriter.WriteLine("Test Case: " + testCasesList[counter]);
                                    resultWriter.WriteLine("Passed:" + "Yes");
                                    resultWriter.WriteLine("Test: " + cmd.ExecuteScalar());
                                }
                            }
                        }
                        counter++;
                    }           
                }
            }           

        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }

    }

在这一行:object query = cmd.ExecuteScalar();查询始终显示为空。如果我不通过任何参数,该语句是否完美?我错过了什么?

【问题讨论】:

    标签: c# sql parameter-passing


    【解决方案1】:

    虽然它不会完全阻止您的查询运行,但我认为您不会得到您想要的结果,因为您无法参数化列名,因此您的查询必须采用以下形式:

    SELECT * FROM claim_header WHERE columnname = @testcase;
    

    并且您有一个或多个查询,具体取决于您要搜索的列

    如果您提供如下 SQL:

    SELECT * FROM claim_header WHERE @columnname = @testcase;
    

    您真正可以对此类查询做的唯一事情是将两个参数设置为相同的值(在这种情况下,您将从表中获取所有行,因为这就像说 SELECT * FROM table WHERE 1=1 )或将它们设置为不同的值,在这种情况下,您将在结果中得到 0 行(因为这就像说 SELECT * FROM table WHERE 1=0)

    如果你想要动态的列名,你真的必须在你的资源文件中这样写你的 SQL:

    SELECT * FROM claim_header WHERE {0} = @testcase;
    

    你的代码是这样的:

    string sqlCommand = string.Format(Resources.Whatever.SQL, elementName);
    

    因此,{0} 被替换为“claim_id”或类似名称。但请注意SQL injection 的危险

    【讨论】:

    • Resources.Whatever.SQL - 这部分不适合我,有什么想法吗?无需担心 SQL 注入,它用于内部测试自动化
    • 我得到了它使用这个:string.Format(EmbeddedResource.GetString("PassQuery.sql"), elementName。谢谢!
    【解决方案2】:

    没有看到你的 SQL 语句,很难说。但是,我敢说这是您的字符串处理中的一个错误。你有这条线:

    cmd.Parameters.AddWithValue("@testcase", "'" + testCasesList[counter] + "'");
    

    您明确地将字符串包装在 ''s 中。这在使用命令参数时是不必要的。任何需要完成的转义都将由 .NET 数据提供程序执行(尽管可能不需要转义——大多数 RDBMS 提供了一种直接传递参数的方法,而无需将参数转换为字符串并插入到 SQL 中)。

    【讨论】:

      【解决方案3】:

      创建参数时不需要加单引号

      改变

      cmd.Parameters.AddWithValue("@testcase", "'" + testCasesList[counter] + "'");
      

      cmd.Parameters.AddWithValue("@testcase", testCasesList[counter]);
      

      【讨论】:

      • 谢谢,我不确定,我添加它们只是为了看看它是否有所作为
      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 2011-10-26
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多