沿边字符串向sql数据库插入byte()

hs1ihplo  于 2021-07-29  发布在  Java
关注(0)|答案(3)|浏览(408)

下面是存储在dao文件中的预定义sql语句。这些值来自一个类。picture值是转换为byte()的图像。这个类是用vb.net编写的。我在一份新工作中,在以前的工作中,我使用了angular和实体框架,所以编写sql语句对我来说是新的。我试着按照现有的例子从同事,但他们从来没有插入图像到数据库之前,所以我有点对我自己。是的,我知道我可以将文件存储在服务器中,并将指向它们的路径保存在数据库中,但无论出于何种原因,我的网络团队都希望将其作为blob存储在数据库中。下面是sql语句。

"INSERT INTO AuthAccessID" &
                      "(" &
                      "FName," &
                      "MName," &
                      "LName," &
                      "Suffix," &
                      "Address," &
                      "AddressExt," &
                      "City," &
                      "State," &
                      "Zip," &
                      "LawFirm," &
                      "Picture," &
                      "AddedDate," &
                      "AddedBy," &
                      ")" &
                      "VALUES(" &
                      "" & ReplaceApostrophes(pp.FName) & ", " &
                      "'" & ReplaceApostrophes(pp.MName) & "', " &
                      "'" & ReplaceApostrophes(pp.LName) & "', " &
                      "'" & ReplaceApostrophes(pp.Suffix) & "', " &
                      "'" & ReplaceApostrophes(pp.Address) & "', " &
                      "'" & ReplaceApostrophes(pp.AddressExt) & "', " &
                      "'" & ReplaceApostrophes(pp.City) & "', " &
                      "'" & ReplaceApostrophes(pp.State) & "', " &
                      "'" & ReplaceApostrophes(pp.Zip) & "', " &
                      "'" & ReplaceApostrophes(pp.LawFirm) & "', " &
                      "'" & pp.Picture & "', " &
                      "'" & pp.AddedDate & "', " &
                      "'" & ReplaceApostrophes(pp.AddedBy) & "')

pp.picture是byte()。我得到的错误是:

Operator '&' is not defined for types 'String' and 'Byte()'

我搜索了一下,但什么也找不到。有人知道怎么纠正吗?还是有更好的方法来编写sql语句?如果我做不到这一点,网络团队说我可以使用服务器文件方法,但是他们实际上是在推动sql存储中的blob。提前谢谢。

fslejnso

fslejnso1#

始终使用参数来避免sql注入,使sql语句更易于编写和读取,并确保发送的数据类型正确。参数也允许撇号。使用 .Add 方法。看到了吗http://www.dbdelta.com/addwithvalue-is-evil/ 以及https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ 还有一个:https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications 这是另一个https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
在下面的代码中,我不得不猜测 SqlDbType 和大小。检查数据库以获取正确的信息。
连接和命令正在使用非托管资源。它们在.dispose方法中释放这些资源,因此必须调用此方法。 Using...End Using 块负责关闭和处理对象,即使有错误。
我假设pp是一个类的示例。我给全班起名叫person。将其更正为真实的类名。

Private ConStr As String = "Your connection string"

Private Sub InsertAuthAccessID(pp As Person)
    Dim sql = "INSERT INTO AuthAccessID (
                  FName,
                  MName,
                  LName,
                  Suffix,
                  Address,
                  AddressExt,
                  City,
                  State,
                  Zip,
                  LawFirm,
                  Picture,
                  AddedDate,
                  AddedBy)
                  VALUES (
                  @FName, 
                  @MName, 
                  @LName, 
                  @Suffix,
                  @Address,
                  @AddressExt,
                  @City,
                  @State,
                  @Zip,
                  @LawFirm,
                  @Picture, 
                  @AddedDate,
                  @AddedBy)"
    Using cn As New SqlConnection(ConStr),
            cmd As New SqlCommand(sql, cn)
        cmd.Parameters.Add("@FName", SqlDbType.VarChar, 50).Value = pp.FName
        cmd.Parameters.Add("@MName", SqlDbType.VarChar, 50).Value = pp.MName
        cmd.Parameters.Add("@LName", SqlDbType.VarChar, 100).Value = pp.LName
        cmd.Parameters.Add("@Suffix", SqlDbType.VarChar, 20).Value = pp.Suffix
        cmd.Parameters.Add("@Address", SqlDbType.VarChar, 200).Value = pp.Address
        cmd.Parameters.Add("@AddressExt", SqlDbType.VarChar, 50).Value = pp.AddressExt
        cmd.Parameters.Add("@City", SqlDbType.VarChar, 100).Value = pp.City
        cmd.Parameters.Add("@State", SqlDbType.VarChar, 50).Value = pp.State
        cmd.Parameters.Add("@Zip", SqlDbType.VarChar, 20).Value = pp.Zip
        cmd.Parameters.Add("@LawFirm", SqlDbType.VarChar, 200).Value = pp.LawFirm
        cmd.Parameters.Add("@Picture", SqlDbType.VarBinary).Value = pp.Picture
        cmd.Parameters.Add("@AddedDate", SqlDbType.Date).Value = pp.AddedDate
        cmd.Parameters.Add("@AddedBy", SqlDbType.VarChar, 50).Value = pp.AddedBy
        cn.Open()
        cmd.ExecuteNonQuery()
    End Using
End Sub

编辑:
在不支持多行的旧版本vb中 String 文本,可以改用xml文本:

Dim sql = <sql>
            INSERT INTO AuthAccessID (
              FName,
              MName,
              LName,
              Suffix,
              Address,
              AddressExt,
              City,
              State,
              Zip,
              LawFirm,
              Picture,
              AddedDate,
              AddedBy)
              VALUES (
              @FName, 
              @MName, 
              @LName, 
              @Suffix,
              @Address,
              @AddressExt,
              @City,
              @State,
              @Zip,
              @LawFirm,
              @Picture, 
              @AddedDate,
              @AddedBy)
           </sql>

Using cn As New SqlConnection(ConStr),
      cmd As New SqlCommand(sql.Value, cn)
gg58donl

gg58donl2#

太长太复杂,无法发表评论。您的代码中有以下代码段:

")" &
                  "VALUES(" &
                  "" & ReplaceApostrophes(pp.FName) & ", " &
                  "'" & ReplaceApostrophes(pp.MName) & "', " &

那是个错误。fname是一个字符串,必须以与mname完全相同的方式进行处理。它缺少单引号分隔符。
更一般地说,这种方法依赖于将所有“字段”转换成文本,以便将它们作为字符串嵌入tsql语句中。所以现在的问题变成了如何在tsql中“编写”二进制文本。您可以通过如下方式生成一个字符串:0x69048aefdd010e。tsql常量的文档在这里。知道了这一点,下一个问题是如何用您的dev语言做到这一点-这不是我能回答的。这看起来很有希望。
但是在你走这条路之前,使用参数化,你就再也不用处理这个问题了。

ruarlubt

ruarlubt3#

我来自msaccess的背景,所以我编写代码的方式与我在vba或现在在vb.net中所做的非常相似
下面是我将使用的代码:

Dim sFields() As String

    sFields = Split("FName,MName,LName,Suffix,Address,AddressExt,City,State,Zip,LawFirm,AddedDate,AddedBy", ",")

    Dim rst As DataTable
    Dim da As SqlDataAdapter

    rst = MyrstEdit("select * from AuthAccessID where id = 0", da, strcon)

    With rst.Rows.Add
        For Each s In sFields
            .Item(s) = GetValue(pp, s)
        Next
    End With
    da.Update(rst)

我有两个助手程序。第一个通过“string”值获取任何类属性。
因为幸运的是,您有字段名,并且类成员是相同的!

Public Function GetValue(ByRef parent As Object, ByVal fieldName As String) As Object

    Dim field As FieldInfo = parent.[GetType]().GetField(fieldName, BindingFlags.[Public] Or BindingFlags.Instance)
    Return field.GetValue(parent)

End Function

然后我有一个数据表例程-它让我得到数据表,是这样的:

Public Function MyrstEdit(strSQL As String, ByRef oReader As SqlDataAdapter) As DataTable

    Dim mycon As New SqlConnection(strCon)
    oReader = New SqlDataAdapter(strSQL, mycon)
    Dim rstData As New DataTable
    Dim cmdBuilder = New SqlCommandBuilder(oReader)
    Try
        oReader.Fill(rstData)
        oReader.AcceptChangesDuringUpdate = True
    Catch
    End Try
    Return rstData

End Function

那么,要得到所有的数据类型和结构?我传递一个不返回任何行的伪sql(不返回任何行,但在执行此虚拟表拉取操作时,确实会得到有价值的表数据类型!)。在大多数情况下,如果pk是一个autonumber,那么我使用id=0。
同样的myrstedit()代码位有很多用途!您现在可以在一个好的结构中处理一个表,循环它,将它放入一个组合框或datagrid中。如图所示,它还允许编辑数据-所有这些都带有类型检查。
我在这里分享的真正诀窍和窍门是什么?将常见的数据例程分解为大约2-3个例程,比如myrstedit()。
这样,您就不必处理凌乱的内嵌sql,或者每次需要处理一个表时,就不必编写成堆的代码。这里真正的美妙之处在于,数据类型是为您完成的—您没有一行接一行的参数,也没有为每一列输入一行接一行的数据。
所以,我希望这篇文章能给你一些想法。但这也很好,因为我的代码非常像我在msaccess中所做的,这包括为这样的更新编写很少的代码。
这里的想法只是-一种不同的方法。这里的其他方法也很好(但是代码比我要多些)。
有时使用数据表是一个很好的例子,我认为这就是这样一个例子。
虽然我经常引用列作为表集合?这里最酷的技巧是我还用一个字符串引用类的每个成员!

相关问题