c# - 在.net中使用SqlCommand使用参数修改数据库
问题描述
我必须根据某些输入动态修改 SQL Server 数据库。我想做的是生成修改命令然后执行它们。而且,为了避免 SQL 注入,我想使用参数。但它不起作用。
这是我的 PoC 代码片段(只是一个粗略的东西):
public static void ModifyDatabase(string name)
{
string connectionString = "Server=localhost; Database=DEV_Tests; Integrated Security=True;";
var sqlCommand = "CREATE SCHEMA @schemaname";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sqlCommand, connection))
{
connection.Open();
command.Parameters.AddWithValue("@schemaname", name);
command.ExecuteNonQuery();
connection.Close();
}
}
这会引发语法错误。但这一个有效:
public static void ModifyDatabase()
{
string connectionString = "Server=localhost; Database=DEV_Tests; Integrated Security=True;";
var sqlCommand = "CREATE SCHEMA AAAA";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sqlCommand, connection))
{
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
}
所以,或者我做错了什么(可能是),或者我不能在“创建模式”中使用参数。事实上,在第二个(没有参数的那个)中,如果我添加一个参数而不使用它,也会失败。是这样吗?如果我们不能在这里使用参数,那么清理输入的最佳方法是什么?修剪它并删除冲突的参数?
谢谢。
解决方案
不能在CREATE
语句中使用参数。相反,使用QUOTENAME
并sp_executesql
动态执行它:
DECLARE @sql nvarchar(max) = N'CREATE SCHEMA ' + QUOTENAME(@schema);
EXEC sp_executesql @sql;
如果您有任何其他可在查询中使用的参数,那么您也可以将其传递给sp_executesql
。
您应该通过 as 传递架构名称nvarchar(128)
,这是相同的sysname
:
command.Parameters.Add("@schemaname", SqlDbType.NVarChar, 128).Value = name;
另一个小提示:为了避免养成连接/注入 SQL 的习惯,我总是将我的查询变量声明为const string query
.
推荐阅读
- javascript - 使用javascript屏幕录制浏览器窗口
- c++ - 启动另一个程序(客户端-服务器)的 C++ 程序
- facebook-graph-api - Facebook Graph - Instagram - “(#3) 应用程序必须在白名单中”
- java - java juint测试选择哪个delta以避免浮点错误
- tokenize - 如何有效地标记文本?
- laravel - 如何排除 .php 文件被 laravel mix 监视
- vb.net - 从文本文件中查找经过的时间
- c# - 字段名没有默认值
- spring-mvc - 发送除表单字段外的额外参数
- node.js - 如何使用 npm 链接启动带有快速服务器的包?