Sdílet prostřednictvím


Úprava vysokých (maximálních) hodnot v ADO.NET

Datové typy velkého objektu (LOB) jsou ty, které překračují maximální velikost řádku 8 kilobajtů (kB). SQL Server poskytuje max specifikátor pro varchar, nvarchara varbinary datové typy umožňující ukládání hodnot tak velké jako 2^32 bajtů. Sloupce tabulek a proměnné jazyka Transact-SQL mohou určovat varchar(max), nvarchar(max)nebo varbinary(max) datové typy. V ADO.NET max lze datové typy načíst pomocí parametru DataReadera lze je také zadat jako hodnoty vstupních i výstupních parametrů bez jakéhokoli speciálního zpracování. U velkých varchar datových typů je možné data načíst a aktualizovat přírůstkově.

Datové max typy lze použít pro porovnání, jako proměnné jazyka Transact-SQL a pro zřetězení. Lze je také použít v klauzulích DISTINCT, ORDER BY, GROUP BY příkazu SELECT a také v agregacích, spojeních a poddotazech.

Další informace naleznete v tématu Použití datových typů s velkými hodnotami.

Omezení typů velkých hodnot

Následující omezení platí pro max datové typy, které neexistují pro menší datové typy:

  • A sql_variant nemůže obsahovat velký varchar datový typ.

  • Velké varchar sloupce nelze zadat jako klíčový sloupec v indexu. Jsou povoleny v zahrnuté sloupci v neskupeném indexu.

  • Velké varchar sloupce nelze použít jako sloupce klíče dělení.

Práce s velkými typy hodnot v transact-SQL

Funkce Transact-SQL OPENROWSET je jednorázová metoda připojení a přístupu ke vzdáleným datům. Obsahuje všechny informace o připojení potřebné pro přístup ke vzdáleným datům ze zdroje dat OLE DB. OPENROWSET lze odkazovat v klauzuli FROM dotazu, jako by se jednalo o název tabulky. Lze na ni také odkazovat jako na cílovou tabulku příkazu INSERT, UPDATE nebo DELETE, která podléhá schopnostem zprostředkovatele OLE DB.

Funkce OPENROWSET obsahuje BULK zprostředkovatele sady řádků, který umožňuje číst data přímo ze souboru bez načtení dat do cílové tabulky. To umožňuje použití OPENROWSET v jednoduchém příkazu INSERT SELECT.

Argumenty OPENROWSET BULK možností poskytují významnou kontrolu nad tím, kde začít a končit čtení dat, jak řešit chyby a jak se data interpretují. Můžete například určit, že se datový soubor čte jako jeden řádek, sada řádků s jedním sloupcem typu varbinary, varcharnebo nvarchar.

Následující příklad vloží fotku do tabulky ProductPhoto v ukázkové databázi AdventureWorks. Při použití BULK OPENROWSET zprostředkovatele musíte zadat pojmenovaný seznam sloupců, i když do každého sloupce nevkládáte hodnoty. Primární klíč v tomto případě je definován jako sloupec identity a může být vynechán ze seznamu sloupců. Všimněte si, že na konec OPENROWSET příkazu musíte zadat také název korelace, což je v tomto případě ThumbnailPhoto. To koreluje se sloupcem ProductPhoto v tabulce, do které se soubor načítá.

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  

Aktualizace dat pomocí funkce UPDATE . ZÁPIS

Příkaz Transact-SQL UPDATE má novou syntaxi zápisu pro úpravu obsahu varchar(max), nvarchar(max)nebo varbinary(max) sloupců. To vám umožní provádět částečné aktualizace dat. AKTUALIZACE . Syntaxe zápisu je zde zobrazena ve zkrácené podobě:

UPDATE

{ <object> }

SET

{ column_name = { . WRITE ( výraz , @Offset , @Length ) }

Metoda WRITE určuje, že se upraví část hodnoty column_name . Výraz je hodnota, která se zkopíruje do column_name, je počáteční bod, @Offset ve kterém se výraz zapíše, a @Length argument je délka oddílu ve sloupci.

Pokud Pak...
Výraz je nastaven na hodnotu NULL. @Length je ignorována a hodnota v column_name je zkrácena v zadaném @Offsetparametru .
@Offset is NULL Operace aktualizace připojí výraz na konec existující hodnoty column_name a @Length bude ignorován.
@Offset je větší než délka column_name hodnoty. SQL Server vrátí chybu.
@Length is NULL Operace aktualizace odebere všechna data od @Offset konce column_name hodnoty.

Poznámka:

@Length Ani @Offset nemůže být záporné číslo.

Příklad

Tento příklad transact-SQL aktualizuje částečnou hodnotu v DocumentSummary, nvarchar(max) sloupec v tabulce Document v databázi AdventureWorks. Slovo "součásti" se nahrazuje slovem "funkce" zadáním náhradního slova, počátečním umístěním (posunem) slova, které má být nahrazeno v existujících datech, a počtem znaků, které se mají nahradit (délka). Příklad obsahuje příkazy SELECT před a za příkazEM UPDATE pro porovnání výsledků.

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.  

Práce s typy velkých hodnot v ADO.NET

V ADO.NET můžete pracovat s velkými typy hodnot zadáním velkých hodnotových typů jako objektů, které vrátí sadu výsledků, nebo pomocí vyplnění/DataSetSqlDataAdapterDataTable .SqlDataReader SqlParameter Mezi tím, jak pracujete s velkým typem hodnoty a jeho souvisejícím, menším datovým typem, neexistuje žádný rozdíl.

Načtení dat pomocí getSqlBytes

GetSqlBytes Metodu SqlDataReader lze použít k načtení obsahu varbinary(max) sloupce. Následující fragment kódu předpokládá SqlCommand objekt s názvem cmd , který vybere varbinary(max) data z tabulky a SqlDataReader objekt s názvem reader , který načte data jako 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);  
    }  

Načtení dat pomocí GetSqlChars

GetSqlChars Metodu SqlDataReader lze použít k načtení obsahu varchar(max) sloupce.nvarchar(max) Následující fragment kódu předpokládá SqlCommand objekt s názvem cmd , který vybere nvarchar(max) data z tabulky a SqlDataReader objekt s názvem reader , který načte data.

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);  
}  

Načtení dat pomocí GetSqlBinary

GetSqlBinary Metodu lze SqlDataReader použít k načtení obsahu varbinary(max) sloupce. Následující fragment kódu předpokládá SqlCommand objekt s názvem cmd , který vybere varbinary(max) data z tabulky a SqlDataReader objekt s názvem reader , který načte data jako SqlBinary datový proud.

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);  
    }  

Načtení dat pomocí GetBytes

Metoda GetBytes SqlDataReader čte datový proud bajtů ze zadaného posunu sloupce do pole bajtů počínaje zadaným posunem pole. Následující fragment kódu předpokládá SqlDataReader objekt s názvem reader , který načte bajty do bajtového pole. Všimněte si, že na rozdíl od GetSqlBytes, GetBytes vyžaduje velikost pro vyrovnávací paměť pole.

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);  
}  

Načtení dat pomocí metody GetValue

Metoda GetValue SqlDataReader přečte hodnotu ze zadaného posunu sloupce do pole. Následující fragment kódu předpokládá objekt s SqlDataReader názvem reader , který načte binární data z posunu prvního sloupce a potom řetězcová data z druhého sloupce posunu.

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);  
}  

Převod z velkých typů hodnot na typy CLR

Obsah varchar(max) sloupce nebo sloupce nvarchar(max) můžete převést pomocí některé z metod převodu řetězců, například ToString. Následující fragment kódu předpokládá SqlDataReader objekt s názvem reader , který načte data.

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);  
}  

Příklad

Následující kód načte název a LargePhoto objekt z ProductPhoto tabulky v AdventureWorks databázi a uloží ho do souboru. Sestavení je potřeba zkompilovat s odkazem na System.Drawing obor názvů. Metoda GetSqlBytes SqlDataReader vrátí SqlBytes objekt, který zveřejňuje Stream vlastnost. Tento kód použije k vytvoření nového Bitmap objektu a pak ho uloží do gifu 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("{0} is unavailable.", photoName);
                    }
                    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 {0}.", 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

Použití parametrů typu velká hodnota

Velké typy hodnot lze použít v SqlParameter objektech stejným způsobem jako menší typy hodnot v SqlParameter objektech. Velké typy hodnot můžete načíst jako SqlParameter hodnoty, jak je znázorněno v následujícím příkladu. Kód předpokládá, že v ukázkové databázi AdventureWorks existuje následující uložená procedura GetDocumentSummary. Uložená procedura přebírá vstupní parametr s názvem @DocumentID a vrací obsah sloupce DocumentSummary ve výstupním parametru @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  

Příklad

Kód ADO.NET vytvoří SqlConnection a SqlCommand objekty pro spuštění uložené procedury GetDocumentSummary a načte souhrn dokumentu, který je uložen jako velký typ hodnoty. Kód předá hodnotu vstupního parametru @DocumentID a zobrazí výsledky předané zpět ve výstupním @DocumentSummary parametru v okně Konzola.

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

Viz také