【问题标题】:Capturing a SQL INSERT statement with additional values in SQL Server在 SQL Server 中捕获带有附加值的 SQL INSERT 语句
【发布时间】:2016-11-30 14:06:42
【问题描述】:

我的 vb.net 应用程序中有一个 INSERT 语句。一路走来……

 SQL = " Insert into tableA (Value1, Value2, Value3) Values (Mark1, City2, State3) "

我想要做的是将它传递给一个实际插入 SQL 语句的函数。我正在尝试在 LOG 表中插入此 sql 语句的副本。

 Public Function (InsertSQL as String) As Boolean
 nSql = "INSERT INTO tblSQLLOG ( InsertSQL, Date, User) VALUES ( "
 nSql += "'" & InsertSQL + "', "
 nSql += "'" & Now() & "', "
 nSql += CStr(userName) + ") "

 cmd = New SqlCommand(nSql, conn)
 End Function

所以现在如果我检查我的 nSQL,它看起来像......

Insert into tblSQLLOG (insert sql, date,user) values ('insert Insert into tableA (Value1, Value2, Value3) Values ('Mark1', 'City2', 'State3')','11/30/2016 8:46:41 AM', 'Bobby')

在这个插入语句中,我在 Value1 附近遇到了一个错误 - 我不知道我做错了什么。在我看来一切都很好。

【问题讨论】:

  • 你应该使用一个参数
  • 始终使用 SQL 参数。日志可以使用cmd.CommandText
  • 您是否尝试在tableAtblSQLLOG 两个表上插入?
  • 请记住,SO 帖子适用于各个年龄段。连接 SQL 是错误的,而不仅仅是一种不同的方式(并且会导致奇怪的事情,例如您的 Inserting apostrophe strings into sql server 问题)您所拥有的任何特殊限制都不会使以这种方式执行 SQL 成为一个好主意. DV 可能是为了表明——这个问题对其他人没有用处。不知道为什么,只是猜测。
  • 不是我的问题。我跟风 这不是一个好兆头。根据您的代码示例,您自己创建查询、命令(不是一些全局帮助程序类)。因此,您很有可能编写带有参数的正确 sql 插入代码,using 关键字用于连接和命令。为什么不。添加/更改一些代码后,它会变成你的,即使你只更改了一行 - 整个文件也会变成你的

标签: sql sql-server vb.net


【解决方案1】:

你做错了一件大事,那就是你没有使用参数。

Public Function FuncName (InsertSQL as String) As Boolean
 nSql = <sql>INSERT INTO tblSQLLOG 
   ( InsertSQL, [Date], [User]) 
   VALUES 
   ( @InsertSQL, @Date, @User)
 </sql>

 cmd = New SqlCommand(nSql, conn)
 cmd.Parameters.AddWithValue("@InsertSQL", InsertSQL)
 cmd.Parameters.AddWithValue("@Date", DateTime.Now)
 cmd.Parameters.AddWithValue("@User", CStr(userName))

 ' then what? you would use cmd and return true or false

 End Function

PS:还要检查 SQL server 中的审计。

【讨论】:

  • cmd.Parameters.AddWithValue 是“邪恶的”。 ADO.NET 将动态创建参数,每次值更改时都会编译查询的查询计划
  • 法比奥,不完全是。参数只会创建一次,然后您可以更改值 N 次。查询计划OTOH取决于参数化和固定的SQL。
  • 不同意查询计划。对于AddWithValue("@One", "test"),将生成带有参数VARCHAR4(4) 的查询。对于 AddWithValue("@One", "testtest")` 将生成带有参数VARCHAR(8) 的查询。 Sql server 会编译两个不同的查询计划
  • @Fabio,我不确定,但没有明确尝试。你可能是对的。可以将其作为 AddWithValue("@pname", "".PadRight(100)) 执行,然后根据需要设置值。最初将在循环中使用 AddWithValue。如果需要考虑这样的优化,那么我可能会使用 SP 或 CLR 函数。我什至不会在客户端写这样的东西。
  • 显式创建参数就足够了:new SqlParameter With { .ParameterName = "@One", .SqlDbType = SqlDbType.VarChar, .Size = 8};
【解决方案2】:

是的,您应该使用参数。那说问题是你在字符串中有单引号。注意 InsertSQL 的 Replace()

Public Function (InsertSQL as String) As Boolean
 nSql = "INSERT INTO tblSQLLOG ( InsertSQL, Date, User) VALUES ( "
 nSql += "'" & Replace(InsertSQL,"'","''") + "', "
 nSql += "'" & Now() & "', "
 nSql += CStr(userName) + ") "

 cmd = New SqlCommand(nSql, conn)
 End Function

【讨论】:

  • 这可能会导致日期时间出现另一个错误(客户端和服务器可能使用不同的文化)。请改用参数。
  • @CetinBasoz 参数是要走的路。这就是为什么我赞成你的回答。我只是在说明导致错误的原因。
  • 是的,我的意思是建议的那个也容易出错。只是替换单引号无济于事。字符串中可能有双引号 - 即:4" 螺丝。如果你也解决这个问题,那么就会出现更大的 SQL 注入攻击。IOW 我总是反对使用参数以外的建议。
  • @Bobski 干杯 :)
  • @Bobski 他不想复制我的:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多