转义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子句中的语法错误",这是因为特殊字符。
到目前为止,我所看到的例子都不适合我想要做的事情,所以希望有人能帮助我。谢谢。
您的实际查询不需要参数,因为它们可以用于为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