转义sql、c#中的特殊字符

本文关键字:特殊字符 sql 转义 | 更新日期: 2023-09-27 18:15:10

我正在编写一个程序,允许用户选择MS Access表,然后将其导出到特定目的地的.csv文件。问题是,当选择的表包含sql特殊字符时,我得到一个错误。

我对这个主题做了一些研究,我知道我需要使用参数,但我不知道如何实际做到这一点。下面是我的代码示例:

        string destination = Form2.destination;
        string selectString = "SELECT * FROM " + tablename;                      
        string path = destination + "''" + tablename + ".csv"; 
        File.Create(path).Dispose();
        TextWriter tw = new StreamWriter(path);
        OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtDataPath.Text);
        connection.Open();
        DataSet myDataSet = new DataSet();
        OleDbCommand command = new OleDbCommand(selectString,connection);
        OleDbDataAdapter adapter = new OleDbDataAdapter(command.CommandText,connection);
        adapter.Fill(myDataSet, tablename);

到目前为止,如果选择了一个没有特殊字符的表名,则创建了csv文件,看起来很好,但如果它包含'-'之类的内容,则我的程序会产生"FROM子句中的语法错误",这是因为特殊字符。

到目前为止,我所看到的例子都不适合我想要做的事情,所以希望有人能帮助我。谢谢。

转义sql、c#中的特殊字符

您的实际查询不需要参数,因为它们可以用于为WHERE条件或INSERT/UPDATE语句提供值,但不能用于替换表名或列名。

但是,如果表名本身包含特殊字符(例如空格),则
是有问题的。要避免此问题,请将表名括在方括号

中。
string selectString = "SELECT * FROM [" + tablename + "]";

记住,以这种方式连接字符串是非常危险的。如果tablename变量来自未经适当检查的用户输入,则有可能遭受Sql注入攻击。

也不要使用字符串连接来构建路径,有一个非常方便的类用于此

string path = Path.Combine(destination, tablename + ".csv"); 

最后,尝试使用Using语句来封闭连接和其他可丢弃对象,因为它确保正确关闭和处置这些对象,否则可能成为程序稳定性的问题

using(OleDbConnection connection = new OleDbConnection("........"))
using(OleDbCommand command = new OleDbCommand(selectString,connection))
using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
    connection.Open();
    DataSet myDataSet = new DataSet();
    adapter.Fill(myDataSet, tablename);
}

将表名用括号括起来。下面应该是一个有效的命令:

SELECT foo FROM [Le Tablé]

您也可以在没有特殊字符的表名称中添加括号,所以无论如何都要将它们全部括起来,并且很高兴。

首先,像这样将表名括起来:

string selectString = "SELECT * FROM [" + tablename + "]";
第二,像这样参数化你的查询:
command.Parameters.Add("@parametername1here", OleDbType.VarChar).value = "somevalue"
command.Parameters.Add("@parametername2here", OleDbType.VarChar).value = "someothervalue"

试着把你的表名用括号括起来。

SELECT * FROM [Some Table Name]

在我看来,你有两个选择。

第一个更简单的选择是只清理表名:

tableName = tableName.replace("-", "''-");

第二个选项,在这里可能不合适,是让c#通过使用SqlParameter实例自动为您转义名称。类似于(伪代码):

    string selectString = "SELECT * FROM @tableName";                      
    // [...]
    OleDbCommand command = new OleDbCommand(selectString, connection);
    command.AddParameter(new SqlParamter("@tableName", tablename); // auto-escapes