Tabellenwertige Parameter mit go-mssqldb

Tabellenwerte Parameter (TVP) ermöglichen es Ihnen, mehrere Zeilen strukturierter Daten an ein gespeichertes Verfahren oder eine parametrisierte Abfrage zu übergeben. Der Treiber go-mssqldb unterstützt TVP über den Typ mssql.TVP .

Nutze TVPs, wenn du einen stark typisierten Zeilensatz in eine gespeicherte Prozedur oder einen Befehl übergeben und die Spaltenstruktur erhalten musst. Für den Pfad mit der höchsten Durchsatz in eine Zieltabelle verwenden Sie Bulk-Operationen. Wenn Ihre Nutzlast verschachtelt ist oder auf Anwendungsebene bereits im JSON-Format vorliegt, verwenden Sie JSON- und XML-Daten.

Prerequisites

Erstellen Sie einen benutzerdefinierten Tabellentyp und eine gespeicherte Prozedur, die sie akzeptiert:

CREATE TYPE dbo.DepartmentType AS TABLE (
    Name NVARCHAR(50),
    GroupName NVARCHAR(50)
);
GO

CREATE PROCEDURE dbo.InsertDepartments
    @departments dbo.DepartmentType READONLY
AS
BEGIN
    INSERT INTO HumanResources.Department (Name, GroupName)
    SELECT Name, GroupName FROM @departments;
END;
GO

Definiere eine Go-Struktur für die TVP-Zeilen

Erstellen Sie einen Go-Struct-Typ, der mit den Spalten im benutzerdefinierten Tabellentyp übereinstimmt:

type DepartmentRow struct {
    Name      string
    GroupName string
}

Übergebe ein TVP an ein gespeichertes Verfahren

Erstelle einen Wert mssql.TVP mit dem Typnamen und einem Slice von Strukturen und übergebe ihn dann als Parameter:

import (
    "context"
    "database/sql"

    "github.com/microsoft/go-mssqldb"
)

func insertDepartments(ctx context.Context, db *sql.DB, departments []DepartmentRow) error {
    tvp := mssql.TVP{
        TypeName: "dbo.DepartmentType",
        Value:    departments,
    }

    _, err := db.ExecContext(ctx, "dbo.InsertDepartments",
        sql.Named("departments", tvp))
    return err
}

Nennen Sie die Funktion:

departments := []DepartmentRow{
    {Name: "Data Science", GroupName: "Research and Development"},
    {Name: "Cloud Ops", GroupName: "Information Technology"},
    {Name: "Developer Relations", GroupName: "Sales and Marketing"},
}
err := insertDepartments(ctx, db, departments)

Spalten-zu-Feld-Abbildung

Der Treiber ordnet TVP-Spalten Struct-Feldern anhand ihrer Position zu (nicht nach ihrem Namen). Das erste Strukturfeld entspricht der ersten Spalte im Tabellentyp, das zweite Feld der zweiten Spalte, das dritte Feld der dritten Spalte und so weiter für alle Spalten des Tabellentyps.

Um eine Spalte zu überspringen, kannst du keine Struct-Tags verwenden. Ordne oder strukturiere deinen Go-Typ um, damit er zur Spaltenreihenfolge im benutzerdefinierten Tabellentyp passt.

Unterstützte Feldtypen

TVP-Strukturfelder unterstützen dieselben Go-Typen wie reguläre Parameter:

Go-Feldtyp SQL Server-Spaltentyp
string nvarchar
mssql.VarChar varchar
int64, int32, int16, int8 bigint, int, smallint, tinyint
float64, float32 float, real
bool bit
time.Time datetimeoffset
[]byte varbinary
mssql.UniqueIdentifier uniqueidentifier

Leere TVP

Du kannst ein leeres Stück weitergeben. Das gespeicherte Verfahren erhält eine Tabelle mit null Zeilen:

tvp := mssql.TVP{
    TypeName: "dbo.DepartmentType",
    Value:    []DepartmentRow{},
}

Schema-qualifizierter Typname

TypeName muss der benutzerdefinierte Tabellentypname sein (nicht der Zieltabellenname oder der gespeicherte Prozedurname). Befindet sich der Tabellentyp in einem nicht-standardmäßigen Schema, fügen Sie das Schema in TypeNameein:

tvp := mssql.TVP{
    TypeName: "HumanResources.DepartmentType",
    Value:    departments,
}