我有一个(SQL Server 2005)数据库,我想在其中创建视图。在我的代码中,我正在构建一个CREATE VIEW语句,但我能让它工作的唯一方法是构建整个查询字符串并裸露它。我想使用参数,但是这个:
SqlCommand cmd = new SqlCommand("CREATE VIEW @name AS SELECT @body");
cmd.Parameters.AddWithValue("@name", "foo");
cmd.Parameters.AddWithValue("@body", "* from bar");
告诉我“关键字VIEW附近有一个错误”(大概是“@name”) - 不用说"CREATE VIEW foo AS SELECT * FROM bar"
就像一个冠军。
这是不可能的吗?如果没有,在运行CREATE语句之前是否有更好的方法来清理输入?在某些情况下,查询正文可能有用户输入,如果有某种方式我可以说“将其视为单个选择语句的主体”,我会感到更安全。也许我要求的是太奇怪了?
<小时/> 关注11月4日: 好的,是的,我想要的就像SQL注入一样,但是我希望至少最小化(如果不是完全删除)运行此命令并删除表或其他内容的选项。当然,运行的用户因为没有权限放弃任何表,但我认为你明白了。我希望有一种说法,实际上是
"This statement will not alter any existing data in any way{ ... }"
。
现在它编码的方式是像 friol 的答案那样进行字符串连接,但这根本没有消毒。如果我至少可以为可疑人物擦洗它,我会感觉更好,比如;或 - 或者你有什么。我希望可能有一个库函数来为我做擦洗,或者沿着那些行进行擦除。
答案 0 :(得分:4)
参数不仅仅是字符串替换。这就是为什么你的代码不起作用的原因。
就像你不能做的那样
sql =“select * from orders where order_id in(?)”
并传递“1,2,3,5”作为参数。
参数是类型检查的,只能包含标量值IIRC。
答案 1 :(得分:1)
也许我没有正确地理解它,但是阻止你做的是什么:
viewname="foo";
viewwhere="* from bar";
SqlCommand cmd = new SqlCommand("CREATE VIEW "+viewname+" AS SELECT "+viewwhere);
答案 2 :(得分:1)
SQL注入。你想要它,这就是重点。你应该连接这些东西。
答案 3 :(得分:0)
在我看来,您正在尝试使用参数创建动态查询,这不是参数化查询的工作方式。它们不会简单地连接到字符串中。
如果您要阻止的是SQL注入,我要做的是验证视图名称只包含字母数字而不包含T-SQL关键字。关于动态创造身体,我会非常小心。