Enviar y recibir datos incrementalmente con FILESTREAM (ODBC)
Se aplica a: SQL Server Azure SQL Database Azure SQL Instancia administrada Azure Synapse Analytics Analytics Platform System (PDW)
En este ejemplo se muestra cómo utilizar la característica FILESTREAM para enviar y recibir datos incrementalmente con SQLPutData y SQLGetData.
Para obtener más información sobre la característica FILESTREAM, vea Compatibilidad con FILESTREAM (ODBC).
Ejemplo
Antes de compilar y ejecutar este ejemplo, habilite la compatibilidad con FILESTREAM (Habilitar y configurar FILESTREAM).
La primera lista de código ( Transact-SQL) crea una base de datos que usa este ejemplo. La instancia de SQL Server debe tener acceso de escritura para ejecutar este script (por ejemplo, iniciar sesión como una cuenta de sistema local).
La segunda lista de código es el código C++. Debe especificar un servidor; para ello, en la lista de código C++, cambie "MyServer" por un nombre de servidor válido. Asegúrese de que la variable de entorno INCLUDE incluye el directorio que contiene sqlncli.h. Genere la lista de código C++ con odbc32.lib, user32.lib, /D "_UNICODE", /D "UNICODE", odbc32.lib y /EHsc.
La tercera lista de código ( Transact-SQL) elimina la base de datos usada por este ejemplo.
USE master
GO
-- enable file stream
exec sp_configure 'filestream access level', 2
GO
-- create directory for filestream database
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
EXEC xp_cmdshell 'md c:\filestreamdemo'
GO
-- Drop the filestream demo database
IF EXISTS (SELECT name FROM master..sysdatabases WHERE name = 'myfilestreamdb')
DROP DATABASE [myfilestreamdb]
GO
-- Create filestream demo database
CREATE DATABASE [myfilestreamdb] ON PRIMARY
(NAME=[myfilestreamdbprimary], FILENAME='c:\filestreamdemo\dbf.mdf'),
FILEGROUP [fsgrp] CONTAINS FILESTREAM (NAME=[fscnt],FILENAME='c:\filestreamdemo\fscnt')
LOG ON (NAME=[dblog], FILENAME='c:\filestreamdemo\db1.ldf', SIZE=5MB, MAXSIZE=3000MB, FILEGROWTH=5MB)
GO
-- Create table that contain filestream column
CREATE TABLE [myfilestreamdb]..[mydocs]
(
id UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE,
doc VARBINARY(MAX) FILESTREAM
)
GO
// compile with: /D "_UNICODE" /D "UNICODE" odbc32.lib /EHsc
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#define _SQLNCLI_ODBC_
#include <sqlncli.h>
#define SUCCESS(x) (!((x) & 0xFFFE))
#define CHKRC(stmt) do { \
rc = (stmt); \
if (!SUCCESS(rc)) \
throw (RETCODE) rc; \
} while(0);
void PrintError(SQLSMALLINT HandleType, SQLHANDLE Handle) {
RETCODE rc = SQL_SUCCESS;
SQLTCHAR szSqlState[6], szMessage[1024];
SQLSMALLINT i = 1, msgLen = 0;
SQLINTEGER NativeError;
do {
i = 1;
while (SQL_NO_DATA != (rc = SQLGetDiagRec(HandleType, Handle, i, szSqlState, &NativeError, szMessage, sizeof(szMessage)/sizeof(SQLTCHAR), &msgLen)) && SUCCESS(rc)) {
_tprintf(_T("SQLState=%s, NativeError=%ld, Message=%s\r\n"), szSqlState, NativeError, szMessage);
i++;
}
}
while (SQL_NO_DATA != (rc = SQLMoreResults(Handle)) && SUCCESS(rc));
}
int _tmain(int argc, _TCHAR* argv[]) {
RETCODE rc = SQL_SUCCESS;
HENV henv = SQL_NULL_HENV;
HDBC hdbc = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
SQLTCHAR * pszConnection = _T("DRIVER={SQL Server Native Client 10.0};")
_T("Server=MyServer;")
_T("Trusted_Connection=Yes;");
SQLLEN cbBuffer = SQL_DATA_AT_EXEC;
BYTE rgbDoc[1024];
SQLLEN cbDoc;
try {
CHKRC(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &henv));
CHKRC(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0));
CHKRC(SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc));
CHKRC(SQLDriverConnect(hdbc, NULL, pszConnection, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT));
CHKRC(SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt));
CHKRC(SQLPrepare(hstmt, (SQLTCHAR *)_T("INSERT INTO [myfilestreamdb]..[mydocs] VALUES(newid(), ?)"), SQL_NTS));
CHKRC(SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, SQL_SS_LENGTH_UNLIMITED, 0, (SQLPOINTER)1, 0, &cbBuffer));
rc = ::SQLExecute(hstmt);
if (SQL_NEED_DATA == rc) {
SQLPOINTER pParam = NULL;
while (SQL_NEED_DATA == (rc = ::SQLParamData(hstmt, (SQLPOINTER *)&pParam))) {
CHKRC(SQLPutData(hstmt, "Hello ", 6));
CHKRC(SQLPutData(hstmt, "World!", 6));
}
}
CHKRC(SQLFreeStmt(hstmt, SQL_CLOSE));
CHKRC(SQLExecDirect(hstmt, _T("SELECT doc FROM [myfilestreamdb]..[mydocs]"), SQL_NTS));
CHKRC(SQLBindCol(hstmt, 1, SQL_C_BINARY, (SQLPOINTER)rgbDoc, sizeof(rgbDoc), &cbDoc));
CHKRC(SQLFetch(hstmt));
rgbDoc[cbDoc] = '\0';
printf("%s\r\n", (LPSTR)rgbDoc);
}
catch (RETCODE retcode) {
rc = retcode;
}
if (!SUCCESS(rc))
if (hstmt)
PrintError(SQL_HANDLE_STMT, hstmt);
else if (hdbc)
PrintError(SQL_HANDLE_DBC, hdbc);
else if(henv)
PrintError(SQL_HANDLE_ENV, henv);
if (hstmt)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
if (hdbc) {
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
if (henv)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
USE master
GO
-- Drop the filestream demo database
sp_detach_db 'myfilestreamdb'
IF EXISTS (SELECT name FROM master..sysdatabases WHERE name = 'myfilestreamdb')
DROP DATABASE [myfilestreamdb]
EXEC xp_cmdshell 'rd /s /q c:\filestreamdemo'
GO