0

亲爱的人们,我正在使用以下代码将图片的字节发送到流表中:

Dim FirstColumnNames As String = imTable(0) & "_Code, " & imTable(0) & "_Price, " & imTable(0) & "_Title, " & imTable(0) & "_Type, " & imTable(0) & "_Height, " & imTable(0) & "_Width, " & imTable(0) & "_Comments "
Dim FirstFieldsValues As String = "'" & imParam(1) & "', '" & imParam(2) & "', '" & imParam(0) & "', '" & imType.ToString & "', '" & imHeight & "', '" & imWidth & "', '" & imParam(3) & "' "
RemoteSQLcmd = New SqlCommand("INSERT INTO " & imTable(0) & " (" & FirstColumnNames & ")  VALUES (" & FirstFieldsValues & ") ", RemoteSQLConn, RemoteSQLtx)
RemoteSQLcmd.ExecuteNonQuery()
RemoteSQLcmd = New SqlCommand("SELECT * FROM " & imTable(0) & " WHERE " & imTable(0) & "_Code = " & "'" & imParam(1) & "'", RemoteSQLConn, RemoteSQLtx)
AbsRecord = RemoteSQLcmd.ExecuteScalar
Dim imGUID As Guid = Guid.NewGuid()
Dim SecondColumnNames As String = imTable(1) & "_" & imTable(0) & "_ID , " & imTable(1) & "_GUID "
Dim SecondFieldsValues As String = "'" & AbsRecord & "', '" & imGUID.ToString & "'"
RemoteSQLcmd = New SqlCommand("INSERT INTO " & imTable(1) & " (" & SecondColumnNames & ")  VALUES (" & SecondFieldsValues & ") ", RemoteSQLConn, RemoteSQLtx)
RemoteSQLcmd.ExecuteNonQuery()
RemoteSQLcmd = New SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT() " & "FROM " & imTable(1) & " WHERE " & imTable(1) & "_" & imTable(0) & "_ID = " &AbsRecord, RemoteSQLConn, RemoteSQLtx)
RemoteSQLcmd.Parameters.Add("@" & imTable(1) & "_GUID", SqlDbType.UniqueIdentifier).Value = imGUID
Dim tokenObject As Object = RemoteSQLcmd.ExecuteScalar()
tokenReader = RemoteSQLcmd.ExecuteReader(CommandBehavior.SingleRow)
tokenReader.Read()
filePathName = tokenReader.GetSqlString(1)
fileToken = DirectCast(tokenReader(3), Byte())
tokenReader.Close()
Dim sqlFile As SqlFileStream = New SqlFileStream(filePathName.Value, fileToken.Value, FileAccess.Write)

这些表具有流动的结构,即第一张表:

myCommand = New SqlCommand("CREATE TABLE " & TablesStat(0, 0) & _
                    " (" & TablesStat(0, 0) & "_ID int NOT NULL PRIMARY KEY IDENTITY(1,1), " & TablesStat(0, 0) & "_Code varchar(20) NULL, " & TablesStat(0, 0) & "_Price money NULL, " & TablesStat(0, 0) & "_Title varchar(50) NULL, " & TablesStat(0, 0) & "_Type sql_variant NULL, " & TablesStat(0, 0) & "_Height int NULL, " & TablesStat(0, 0) & "_Width int NULL, " & TablesStat(0, 0) & "_Comments nvarchar(MAX) NULL)", RemoteSQLConn)
myCommand.ExecuteNonQuery()

结束第二张表是:

myCommand = New SqlCommand("CREATE TABLE " & TablesStat(1, 0) & _
   " (" & TablesStat(1, 0) & "_ID int NOT NULL PRIMARY KEY IDENTITY(1,1), " & TablesStat(1, 0) & "_GUID UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE , " & TablesStat(1, 0) & "_" & TablesStat(0, 0) & "_ID int FOREIGN KEY REFERENCES " & TablesStat(0, 0) & " (" & TablesStat(0, 0) & "_ID) NOT NULL, " & TablesStat(1, 0) & "_Image varbinary(MAX) FILESTREAM NULL ) ", RemoteSQLConn)

myCommand.ExecuteNonQuery()

当我试图读取 'filePathName' 和 'fileToken' privious SELECT GET_FILESTREAM 时,我的问题就来了....只返回一个列来读取我知道我正在做的具有二进制格式 GUID 的列 0出了点问题,但我不知道是什么

我的问题是我没有得到'filePathName'和fileToken'

有人可以帮助我吗?


看马克斯

我按照你说的做了,但什么也没做

RemoteSQLcmd = New SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", RemoteSQLConn, RemoteSQLtx) 
Dim tokenObject As Object = RemoteSQLcmd.ExecuteScalar() 
tokenReader = RemoteSQLcmd.ExecuteReader(CommandBehavior.SingleRow) 
tokenReader.Read() 
fileToken = DirectCast(tokenReader(1), Byte()) 
filePathName = tokenReader.GetSqlString(3)

并且事务开始远高于此命令

并且永不停止


Dim imGUID As Guid = Guid.NewGuid()
Dim imImage As Byte() = New Byte(imStream.Length) {}
Dim bytesRead As Integer = imStream.Read(imImage, 0, imStream.Length)
Dim SecondColumnNames As String = _
            imTable(1) & "_GUID, " & _
            imTable(1) & "_" & imTable(0) & "_ID"
Dim SecondFieldsValues As String = "'" & imGUID.ToString & "', '" & AbsRecord & "'"
RemoteSQLcmd = New SqlCommand("INSERT INTO " & imTable(1) & _
            " (" & SecondColumnNames & ")  VALUES (" & SecondFieldsValues & ")", RemoteSQLConn, RemoteSQLtx)
RemoteSQLcmd.Parameters.Add("@" & imTable(1) & "_GUID", SqlDbType.UniqueIdentifier).Value = imGUID
  RemoteSQLcmd.Parameters.Add("@" & imTable(1) & "_Image", SqlDbType.Image).Value = imImage
  RemoteSQLcmd.ExecuteNonQuery()
  RemoteSQLcmd = New SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT() FROM " & imTable(1), RemoteSQLConn, RemoteSQLtx)
Dim tokenObject As Object = RemoteSQLcmd.ExecuteScalar()
tokenReader = RemoteSQLcmd.ExecuteReader(CommandBehavior.SingleRow)
tokenReader.Read()

如您所见,我再次输入了 FROM 子句。

但请看看我在阅读器中收到了什么


tokenReader.深度 0

tokenReader.FieldCount 1

tokenReader.HasRows True

tokenReader.IsClosed False

tokenReader.Item 为了评估索引属性,必须限定属性并且参数必须由用户显式提供。

tokenReader.RecordsAffected -1


正如你在这里看到的,我只有一栏要阅读,没有别的

我真的不知道这是否有帮助,但无论如何我把它放在那里

tokenReader.VisibleFieldCount 1

4

1 回答 1

1

MSDN说你应该

  • 在 TRANSACTION 中执行此操作
  • 在没有任何“FROM TABLE”的情况下执行“SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()”

Yan Pan 的 Working with FILESTREAM using VB .NET中有一个示例:

' Obtain a transaction context. All FILESTREAM BLOB operations occur '
' within a transaction context to maintain data consistency. '
Dim transaction As SqlTransaction = 
    sqlConnection.BeginTransaction("mainTranaction")
sqlCommand.Transaction = transaction
sqlCommand.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()"
Dim obj As Object = sqlCommand.ExecuteScalar()
Dim txContext As Byte() = Nothing
If Not obj.Equals(DBNull.Value) Then
    txContext = DirectCast(obj, Byte())
Else
    Throw New System.Exception("GET_FILESTREAM_TRANSACTION_CONTEXT() failed")
End If

' Obtain a handle that can be passed to the Win32 FILE APIs. '
Dim sqlFileStream As New SqlFileStream(filePath, txContext, FileAccess.Write)

' Converting the image to a byte array. '
' Please change C:\Spire.jpg to your image file path. '
Dim byteImg As Byte()
byteImg = File.ReadAllBytes("C:\Spire.jpg")
'Write the image file to the FILESTREAM BLOB. '
sqlFileStream.Write(byteImg, 0, byteImg.Length)

' Close the FILESTREAM handle. '
sqlFileStream.Close()

' Commit the write operation that was performed on the FILESTREAM BLOB. ' 
sqlCommand.Transaction.Commit()

尝试根据示例更改您的代码:

  • filePath 变量在打开文件事务之前启动
  • 文件上下文有一个简单的“SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()”命令
  • 有一个空检查和 DirectCast(obj, Byte()) 将值转换为字节
  • 不确定它是否有区别,但SqlFileStream打开时txContext,不是txContext.Value

更新
我如何理解这个问题:

filePathName- 我们将打开文件流的文件名。这个值应该从你的表的某个字段中选择。如果您不知道 [table].[field] 它是什么,请查看内部 db 表值并查找文件路径的保存位置。

fileToken- 文件流事务上下文。应在单独的命令执行中选择,并强制转换为字节。


SQL 注入意味着当你做类似的事情时

RemoteSQLcmd = New SqlCommand("SELECT * FROM " & imTable(0) & " WHERE " 
    & imTable(0) & "_Code = " & "'" & imParam(1) 
    & "'", RemoteSQLConn, RemoteSQLtx)

在代码隐藏中,imParam它是一个 URL 参数值,有人可能会在你放“'; DROP TABLE users;”时开个坏玩笑 在其中可能会解决

SELECT * FROM table WHERE table_Code = ''; DROP TABLE users;
于 2009-12-31T17:35:34.203 回答