Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Параметры с таблицьными значениями (TVP) позволяют передавать несколько строк структурированных данных в хранимую процедуру или параметризованный запрос.
go-mssqldb драйвер поддерживает TVP с помощью типа mssql.TVP.
Используйте TVP, когда нужно передать сильно типизированный набор строк в сохранённую процедуру или команду, сохраняя структуру на уровне столбцов. Для пути с наибольшей пропускной способностью в таблицу назначения используйте Bulk operations. Если ваша полезная нагрузка является вложенной или уже представлена в формате JSON на уровне приложения, используйте данные JSON и XML.
Prerequisites
Создайте пользовательский тип таблицы и хранящую процедуру, которая его принимает:
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
Определите структуру Go для строк TVP
Создайте тип структуры Go, соответствующий столбцам в пользовательском типе таблицы:
type DepartmentRow struct {
Name string
GroupName string
}
Передайте TVP в сохранённую процедуру
Создайте mssql.TVP значение с именем типа и срезом структур, затем передайте его как параметр:
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
}
Вызовите функцию:
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)
Сопоставление столбцов с полями
Драйвер сопоставляет столбцы TVP с полями структуры по позиции (а не по имени). Первое поле структуры соответствует первому столбцу в типе таблицы, второе поле соответствует второму столбцу, третье поле соответствует третьему столбцу и так далее для всех столбцов в типе таблицы.
Чтобы пропустить столбц, нельзя использовать теги struct. Измените порядок полей или структуру типа Go так, чтобы он соответствовал порядку столбцов в пользовательском табличном типе.
Поддерживаемые типы полей
Поля структуры TVP поддерживают те же типы Go, что и обычные параметры:
| Тип поля Go | Тип столбца SQL Server |
|---|---|
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 |
Пустой TVP
Можно передать пустой кусок. Сохранённая процедура получает таблицу с нулём строк:
tvp := mssql.TVP{
TypeName: "dbo.DepartmentType",
Value: []DepartmentRow{},
}
Название типа, квалифицированное по схеме
TypeName должно быть имя типа таблицы, определённое пользователем (не имя таблицы назначения или имя хранимой процедуры). Если тип таблицы находится в нестандартной схеме, включите схему в TypeName:
tvp := mssql.TVP{
TypeName: "HumanResources.DepartmentType",
Value: departments,
}