Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Типы данных больших объектов (LOB) — это типы данных, превышающие максимальный размер строки размером 8 килобайт (КБ). SQL Server предоставляет спецификатор для max, varchar и nvarchar типов данных, чтобы позволить хранение значений размером до 2^32 байт. Столбцы таблиц и Transact-SQL переменные могут указывать varchar(max)или nvarchar(max)varbinary(max) типы данных. В ADO.NET max типы данных можно получить с помощью DataReader, и их также можно указать как значения входного и выходного параметров без специальной обработки. Для больших varchar типов данных данные можно извлекать и обновлять постепенно.
Типы данных max можно использовать для сравнения, в качестве переменных Transact-SQL и для объединения. Они также могут использоваться в выражениях DISTINCT, ORDER BY, GROUP BY инструкции SELECT, а также в агрегатных функциях, операциях соединения и вложенных запросах.
Дополнительные сведения см. в разделе "Использование типов данных Large-Value".
Ограничения типов Large-Value
Следующие ограничения применяются к типам max данных, которые не существуют для небольших типов данных:
sql_variantне может содержать крупный тип данныхvarchar.Большие
varcharстолбцы нельзя указать в качестве ключевого столбца в индексе. Они разрешены в включенном столбце в некластеризованном индексе.Большие
varcharстолбцы нельзя использовать в качестве секционирования ключевых столбцов.
Работа с типами Large-Value в Transact-SQL
Функция Transact-SQL OPENROWSET — это одноразовый метод подключения и доступа к удаленным данным. Он содержит все сведения о подключении, необходимые для доступа к удаленным данным из источника данных OLE DB.
OPENROWSET можно ссылаться в предложении FROM запроса, как будто это имя таблицы. Она также может быть указана в качестве целевой таблицы инструкции INSERT, UPDATE или DELETE при условии возможностей поставщика OLE DB.
Функция OPENROWSET включает поставщика набора строк BULK, который позволяет напрямую считывать данные из файла без загрузки данных в целевую таблицу. Это позволяет использовать OPENROWSET в простой инструкции INSERT SELECT.
Аргументы OPENROWSET BULK параметра обеспечивают значительный контроль над началом и завершением чтения данных, способом обработки ошибок и интерпретацией данных. Например, можно указать, что файл данных считывается как набор строк, состоящий из одной строки и одного столбца, типа varbinary, varchar или nvarchar.
В следующем примере фотография вставляется в таблицу ProductPhoto в примере базы данных AdventureWorks. При использовании BULK OPENROWSET поставщика необходимо указать именованный список столбцов, даже если вы не вставляете значения в каждый столбец. Первичный ключ в этом случае определяется как столбец идентификатора и может быть опущен из списка столбцов. Обратите внимание, что необходимо также указать имя корреляции в конце инструкции OPENROWSET , которая в данном случае — ThumbnailPhoto. Это коррелирует с столбцом в ProductPhoto таблице, в которую загружается файл.
INSERT Production.ProductPhoto (
ThumbnailPhoto,
ThumbnailPhotoFilePath,
LargePhoto,
LargePhotoFilePath)
SELECT ThumbnailPhoto.*, null, null, N'tricycle_pink.gif'
FROM OPENROWSET
(BULK 'c:\images\tricycle.jpg', SINGLE_BLOB) ThumbnailPhoto
Обновление данных с помощью UPDATE .WRITE
Инструкция Transact-SQL UPDATE имеет новый синтаксис WRITE для изменения содержимого столбцов varchar(max), nvarchar(max) или varbinary(max). Это позволяет выполнять частичные обновления данных. Синтаксис UPDATE .WRITE показан здесь в сокращенной форме:
Обновление
{ <object> }
УСТАНОВКА
{ column_name = { .WRITE ( выражение , @Offset , @Length ) }
Метод WRITE указывает, что будет изменен раздел значения column_name . Выражение — это значение, которое будет скопировано в column_name, @Offset является начальной точкой, в которой будет записано выражение, а @Length аргумент — длина раздела в столбце.
| Если | Затем |
|---|---|
| Выражение имеет значение NULL |
@Length игнорируется, а значение в column_name усечено по указанному параметру @Offset. |
@Offset имеет значение NULL |
Операция обновления добавляет выражение в конец существующего значения в имя_столбца, при этом @Length игнорируется. |
@Offset больше, чем длина значения столбца column_name |
SQL Server возвращает ошибку. |
@Length имеет значение NULL |
Операция обновления удаляет все данные с @Offset до конца значения column_name. |
Замечание
Ни @Offset ни @Length не могут быть отрицательным числом.
Пример
Этот пример Transact-SQL показывает, как обновить частичное значение в DocumentSummary, nvarchar(max) столбце таблицы Document в базе данных AdventureWorks. Слово "компоненты" заменяется словом "функции" путем указания слова замены, начального расположения (смещения) слова, заменяемого в существующих данных, и количества символов, которые необходимо заменить (длина). В примере содержатся инструкции SELECT до и после инструкции UPDATE для сравнения результатов.
USE AdventureWorks;
GO
--View the existing value.
SELECT DocumentSummary
FROM Production.Document
WHERE DocumentID = 3;
GO
-- The first sentence of the results will be:
-- Reflectors are vital safety components of your bicycle.
--Modify a single word in the DocumentSummary column
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
WHERE DocumentID = 3 ;
GO
--View the modified value.
SELECT DocumentSummary
FROM Production.Document
WHERE DocumentID = 3;
GO
-- The first sentence of the results will be:
-- Reflectors are vital safety features of your bicycle.
Работа с типами Large-Value в ADO.NET
Вы можете работать с большими типами значений в ADO.NET, указав большие типы значений в качестве SqlParameter объектов в SqlDataReader результирующем SqlDataAdapter наборе, или используя SqlDataAdapter, чтобы заполнить /DataTable. Нет разницы между способом работы с большим типом значений и соответствующим типом данных меньшего значения.
Получение данных с помощью GetSqlBytes
Метод GetSqlBytes в SqlDataReader можно использовать для извлечения содержимого столбца varbinary(max). В следующем фрагменте кода предполагается, что существует объект SqlCommand с именем cmd, который выбирает varbinary(max) данные из таблицы, и объект SqlDataReader с именем reader, который извлекает данные как SqlBytes.
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While reader.Read()
Dim bytes As SqlBytes = reader.GetSqlBytes(0)
End While
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
SqlBytes bytes = reader.GetSqlBytes(0);
}
Использование GetSqlChars для извлечения данных
Метод GetSqlCharsSqlDataReader можно использовать для извлечения содержимого столбца varchar(max) или столбца nvarchar(max). В следующем фрагменте кода предполагается, что объект SqlCommand с именем cmd выбирает данные nvarchar(max) из таблицы, а объект SqlDataReader с именем reader извлекает данные.
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While reader.Read()
Dim buffer As SqlChars = reader.GetSqlChars(0)
End While
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
SqlChars buffer = reader.GetSqlChars(0);
}
Использование GetSqlBinary для извлечения данных
Метод GetSqlBinary объекта SqlDataReader можно использовать для извлечения содержимого столбца varbinary(max) . В следующем фрагменте кода предполагается SqlCommand объект с именемcmd, который выбирает данные из таблицы и varbinary(max) объект с именемSqlDataReader, который извлекает reader данные в виде SqlBinary потока.
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While reader.Read()
Dim binaryStream As SqlBinary = reader.GetSqlBinary(0)
End While
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
SqlBinary binaryStream = reader.GetSqlBinary(0);
}
Использование GetBytes для извлечения данных
Метод GetBytesSqlDataReader считывает поток байтов из указанного отступа столбца в байтовый массив, начиная с указанного отступа массива. В следующем фрагменте кода предполагается объект SqlDataReader, который с именем reader извлекает байты в массив байтов. Обратите внимание, что, в отличие от GetSqlBytes, для GetBytes требуется размер буфера массива.
While reader.Read()
Dim buffer(4000) As Byte
Dim byteCount As Integer = _
CInt(reader.GetBytes(1, 0, buffer, 0, 4000))
End While
while (reader.Read())
{
byte[] buffer = new byte[4000];
long byteCount = reader.GetBytes(1, 0, buffer, 0, 4000);
}
Использование GetValue для извлечения данных
Метод GetValueSqlDataReader считывает значение из указанного столбца и помещает его в массив. Следующий фрагмент кода предполагает объект с именемSqlDataReader, который извлекает reader двоичные данные из смещения первого столбца, а затем строковые данные из смещения второго столбца.
While reader.Read()
' Read the data from varbinary(max) column
Dim binaryData() As Byte = CByte(reader.GetValue(0))
' Read the data from varchar(max) or nvarchar(max) column
Dim stringData() As String = Cstr((reader.GetValue(1))
End While
while (reader.Read())
{
// Read the data from varbinary(max) column
byte[] binaryData = (byte[])reader.GetValue(0);
// Read the data from varchar(max) or nvarchar(max) column
String stringData = (String)reader.GetValue(1);
}
Преобразование из типов Large Value в типы CLR
Можно преобразовать содержимое столбца varchar(max) с помощью любого из методов преобразования строк, таких как nvarchar(max). В следующем фрагменте кода предполагается объект SqlDataReader с именем reader, который извлекает данные.
While reader.Read()
Dim str as String = reader(0).ToString()
Console.WriteLine(str)
End While
while (reader.Read())
{
string str = reader[0].ToString();
Console.WriteLine(str);
}
Пример
Следующий код извлекает имя и LargePhoto объект из ProductPhoto таблицы в AdventureWorks базе данных и сохраняет его в файл. Сборка должна быть скомпилирована со ссылкой на System.Drawing пространство имен. Метод GetSqlBytes, принадлежащий SqlDataReader, возвращает объект SqlBytes, который содержит свойство Stream. Этот код используется для создания нового Bitmap объекта, а затем сохраняет его в GIF ImageFormat.
static void TestGetSqlBytes(int documentID, string filePath)
{
// Assumes GetConnectionString returns a valid connection string.
using (SqlConnection connection =
new(GetConnectionString()))
{
SqlCommand command = connection.CreateCommand();
SqlDataReader reader = default!;
try
{
// Setup the command
command.CommandText =
"SELECT LargePhotoFileName, LargePhoto "
+ "FROM Production.ProductPhoto "
+ "WHERE ProductPhotoID=@ProductPhotoID";
command.CommandType = CommandType.Text;
// Declare the parameter
SqlParameter paramID =
new("@ProductPhotoID", SqlDbType.Int)
{
Value = documentID
};
command.Parameters.Add(paramID);
connection.Open();
string photoName = default!;
reader = command.ExecuteReader(CommandBehavior.CloseConnection);
if (reader.HasRows)
{
while (reader.Read())
{
// Get the name of the file.
photoName = reader.GetString(0);
// Ensure that the column isn't null
if (reader.IsDBNull(1))
{
Console.WriteLine($"{photoName} is unavailable.");
}
else
{
SqlBytes bytes = reader.GetSqlBytes(1);
using (Bitmap productImage = new(bytes.Stream))
{
var fileName = filePath + photoName;
// Save in gif format.
productImage.Save(fileName, ImageFormat.Gif);
Console.WriteLine($"Successfully created {fileName}.");
}
}
}
}
else
{
Console.WriteLine("No records returned.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
reader?.Dispose();
}
}
}
Private Sub GetPhoto(
ByVal documentID As Integer, ByVal filePath As String)
' Assumes GetConnectionString returns a valid connection string.
Using connection As New SqlConnection(GetConnectionString())
Dim command As SqlCommand = connection.CreateCommand()
Dim reader As SqlDataReader
Try
' Setup the command
command.CommandText =
"SELECT LargePhotoFileName, LargePhoto FROM" _
& " Production.ProductPhoto" _
& " WHERE ProductPhotoID=@ProductPhotoID"
command.CommandType = CommandType.Text
' Declare the parameter
Dim paramID As SqlParameter =
New SqlParameter("@ProductPhotoID", SqlDbType.Int)
paramID.Value = documentID
command.Parameters.Add(paramID)
connection.Open()
Dim photoName As String
reader =
command.ExecuteReader(CommandBehavior.CloseConnection)
If reader.HasRows Then
While reader.Read()
' Get the name of the file
photoName = reader.GetString(0)
' Ensure that the column isn't null
If (reader.IsDBNull(1)) Then
Console.WriteLine("{0} is unavailable.", photoName)
Else
Dim bytes As SqlBytes = reader.GetSqlBytes(1)
Using productImage As New Bitmap(bytes.Stream)
Dim fileName As String = filePath & photoName
' Save in gif format.
productImage.Save(
fileName, ImageFormat.Gif)
Console.WriteLine("Successfully created {0}.", fileName)
End Using
End If
End While
Else
Console.WriteLine("No records returned.")
End If
Catch ex As Exception
Console.WriteLine("Exception: {0}", ex.Message)
End Try
End Using
End Sub
Использование параметров больших типов значений
Крупные типы значений можно использовать в SqlParameter объектах так же, как и в объектах меньшего размера SqlParameter . Вы можете получить большие типы значений в виде SqlParameter значений, как показано в следующем примере. В коде предполагается, что в примере базы данных AdventureWorks существует следующая хранимая процедура GetDocumentSummary. Хранимая процедура принимает входной параметр с именем @DocumentID и возвращает содержимое столбца DocumentSummary в выходном параметре @DocumentSummary .
CREATE PROCEDURE GetDocumentSummary
(
@DocumentID int,
@DocumentSummary nvarchar(MAX) OUTPUT
)
AS
SET NOCOUNT ON
SELECT @DocumentSummary=Convert(nvarchar(MAX), DocumentSummary)
FROM Production.Document
WHERE DocumentID=@DocumentID
Пример
Код ADO.NET создает SqlConnection и SqlCommand объекты для выполнения хранимой процедуры GetDocumentSummary и получения сводки документа, которая хранится как большой тип значения. Код передает значение входного @DocumentID параметра и отображает результаты, переданные обратно в выходной @DocumentSummary параметр в окне консоли.
static string? GetDocumentSummary(int documentID)
{
// Assumes GetConnectionString returns a valid connection string.
using (SqlConnection connection =
new(GetConnectionString()))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
try
{
// Set up the command to execute the stored procedure.
command.CommandText = "GetDocumentSummary";
command.CommandType = CommandType.StoredProcedure;
// Set up the input parameter for the DocumentID.
SqlParameter paramID =
new("@DocumentID", SqlDbType.Int)
{
Value = documentID
};
command.Parameters.Add(paramID);
// Set up the output parameter to retrieve the summary.
SqlParameter paramSummary =
new("@DocumentSummary",
SqlDbType.NVarChar, -1)
{
Direction = ParameterDirection.Output
};
command.Parameters.Add(paramSummary);
// Execute the stored procedure.
command.ExecuteNonQuery();
Console.WriteLine((string)paramSummary.Value);
return (string)paramSummary.Value;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
}
Private Function GetDocumentSummary( _
ByVal documentID As Integer) As String
' Assumes GetConnectionString returns a valid connection string.
Using connection As New SqlConnection(GetConnectionString())
connection.Open()
Dim command As SqlCommand = connection.CreateCommand()
' Setup the command to execute the stored procedure.
command.CommandText = "GetDocumentSummary"
command.CommandType = CommandType.StoredProcedure
' Set up the input parameter for the DocumentID.
Dim paramID As SqlParameter = _
New SqlParameter("@DocumentID", SqlDbType.Int)
paramID.Value = documentID
command.Parameters.Add(paramID)
' Set up the output parameter to retrieve the summary.
Dim paramSummary As SqlParameter = _
New SqlParameter("@DocumentSummary", _
SqlDbType.NVarChar, -1)
paramSummary.Direction = ParameterDirection.Output
command.Parameters.Add(paramSummary)
' Execute the stored procedure.
command.ExecuteNonQuery()
Console.WriteLine(paramSummary.Value)
Return paramSummary.Value.ToString
End Using
End Function