【问题标题】:Inserting NULL values in a database from VBA code从 VBA 代码在数据库中插入 NULL 值
【发布时间】:2017-04-20 14:05:33
【问题描述】:

我有 3 个单选按钮(“YES”、“NO”、“UNKNOWN”),它们与我数据库中的一个列与 3 个可能的值(1、0、NULL)匹配。

When the radioButton selected is "UNKNOWN" I want to insert a NULL value in this table (using Variant type).但是当我尝试使用我的 ADODB 连接运行我的 SQL 查询时,它会返回一个错误。

在我的数据库中传递 NULL 值是否有技巧?这是我的代码的副本:

Public Function setCandidature(idC As Integer, idO As Integer, nomC As String, prenomC As String, nomM As String, prenomM As String, idRegion As Integer, idUM As Integer, idDUM As Integer, nni As String, emploiC As String, repM As Integer, repA As Integer, accDisp As Integer, precAcc1 As Integer, precAcc2 As Integer)
Dim sqlQuery As String
Dim rs As ADODB.Recordset
Dim repAVar As Variant, repMVar As Variant

Set connect = New ADODB.Connection
connect.Open connString

If repA = -1 Then
    repAVar = Null
Else
    repAVar = repA
End If

If repM = -1 Then
    repMVar = Null
Else
    repMVar = repM
End If

sqlQuery = "UPDATE candidatures SET offre_ID = " & idO & ", candidat_Nom = " & nomC & ", candidat_Prenom = " & prenomC & ", manager_Nom = " & nomM & ", manager_Prenom = " & prenomM & ", reponse_Manager = " & repMVar & ", reponse_Agent = " & repAVar & ", region_Candidat = " & idRegion & _
           ", um_Candidat = " & idUM & ", dum_Candidat = " & idDUM & ", nni_Candidat = " & nni & ", emploi_Candidat = " & emploiC & ", accompagnement_Dispense = " & accDisp & ", accompagnement_Precision_ID = " & precAcc1 & ", accompagnement2_Precision_ID = " & precAcc2 & _
           " WHERE candidature_ID = " & idC & ";"

rs.Open sqlQuery, connect
End Function

我首先将希望为 NULL 的值作为包含 -1 的整数传递。

【问题讨论】:

  • 你能试试vbNull 吗?
  • @Vityata 喜欢这个? :repAVar = vbNull
  • 因为它不起作用
  • 是的,我就是这么想的。然后试试repAVar = "Null"

标签: vba adodb


【解决方案1】:

您希望您的 SQL 语句最终看起来像这样:

UPDATE candidatures 
SET offre_ID = 42
   ,candidat_Nom = 'Doe'
   ,candidat_Prenom = 'John'
   ,manager_Nom = 'Nuts'
   ,manager_Prenom = 'Doug'
   ,reponse_Manager = NULL
   ,reponse_Agent = NULL
   ,region_Candidat = 'WEST'
   ,um_Candidat = 72
   ,dum_Candidat = 72
   ,nni_Candidat = 24
   ,emploi_Candidat = 'something'
   ,accompagnement_Dispense = 'whatever'
   ,accompagnement_Precision_ID = 10
   ,accompagnement2_Precision_ID = 11
WHERE candidature_ID = 2345;

您希望字符串用单引号括起来,数值用这种单引号括起来,NULL 值按字面意思指定。

您可以保留字符串连接方法,并通过将 "NULL" 字符串文字连接到查询中来使查询包含 NULL 值:

If repA = -1 Then
    repAVar = "NULL"
Else
    repAVar = repA
End If

If repM = -1 Then
    repMVar = "NULL"
Else
    repMVar = repM
End If

显然这意味着处理何时/是否包含单引号,以及何时

这可能会起作用......直到它不起作用:

UPDATE candidatures 
SET offre_ID = 42
   ,candidat_Nom = 'O'Connor'
   ,candidat_Prenom = 'David'
...

我知道!我将简单地将字符串值中的任何单引号加倍!这可能会起作用:

UPDATE candidatures 
SET offre_ID = 42
   ,candidat_Nom = 'O''Connor'
   ,candidat_Prenom = 'David'
...

但是走下那座山,你就可以兜风了……你会不断修补和“清理”用户的输入,直到一切恢复正常,然后它们崩溃了,你再次修补它……

有一种理智的方法可以做到这一点。

使用参数,让服务器处理参数。

因此,不是将参数值连接到命令字符串中,而是将其发送到服务器:

UPDATE candidatures 
SET offre_ID = ?
   ,candidat_Nom = ?
   ,candidat_Prenom = ?
   ,manager_Nom = ?
   ,manager_Prenom = ?
   ,reponse_Manager = ?
   ,reponse_Agent = ?
   ,region_Candidat = ?
   ,um_Candidat = ?
   ,dum_Candidat = ?
   ,nni_Candidat = ?
   ,emploi_Candidat = ?
   ,accompagnement_Dispense = ?
   ,accompagnement_Precision_ID = ?
   ,accompagnement2_Precision_ID = ?
WHERE candidature_ID = ?;

..以及参数

您不使用Recordset。您改为使用Command

Dim connect As ADODB.Connection
Set connect = New ADODB.Connection
connect.ConnectionString = connString
connect.Open

With New ADODB.Command
    .ActiveConnection = connect
    .CommandType = adCmdText
    .CommandText = sqlQuery

    'append parameters in the same order they show up in the query
    .Parameters.Append .CreateParameter(Type:=adInteger, Direction:=adParamInput, Value:=myValue)

    '...
    .Execute
End With
connect.Close

要给参数一个NULL 值,只需使用Null 关键字:

myValue = Null

这要求您的可为空值具有 Variant 数据类型,因为在 VBA 中 IntegerBoolean 不能是 Null

【讨论】:

  • 我知道当你写一个巨大的答案时的感觉,发布它,看到有人评论了它的本质! :)
  • @Vityata meh.. 我不会给出建议将 "Null" 连接到命令字符串中的答案 - 但我知道它会以某种方式出现。唯一明智的方法是使用参数化命令......而这在 cmets 中是没有的;-)
  • 好的Command 示例。 :) 也许你可以写一个 VBA Wiki?
  • 好吧,给 SQL 注入留点空间,有些人靠它谋生;)
  • 您好,感谢您的回答!我还没有尝试让它工作,但你会建议对每个非 SELECT 查询使用 ADODB.Command 吗?还要感谢有关如何显示我的查询的提示:它确实使我的代码更易于阅读!
【解决方案2】:

只是对未来的一个想法 - 每当您遇到这样的大型 SQL 代码问题时:

sqlQuery = "UPDATE candidatures SET offre_ID = " & idO & ", candidat_Nom = " & more and more more SQL here";"

执行以下操作:

  1. 写入 debug.print sqlQuery 代码后。
  2. 从即时窗口中获取结果并检查它。
  3. 将其复制并放入 Access 查询中。它应该工作。如果没有,请进一步检查和调试。

编辑:如果你有time & knowledge & will to write good code,不要写这样的代码。您可能会遇到SQL injection 和其他问题。而是使用 Mat's Mug 的答案中的方法。

【讨论】:

  • 可以说“每当您遇到像这样的大 SQL 代码时 sqlQuery = "SOME huge SQL statement WITH = " & concatenations & " AND " & moreConcatenations & ";" ...解决方案是摆脱串联。但是是的 +1 用于展示如何使用调试器和立即窗格来解决问题。
  • @Mat'sMug - 摆脱串联正是这样做的方法,不能再同意了。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多