Requêtes de bases de données croisées
S'applique à : SQL Server
À partir de SQL Server 2014 (12.x), les tables mémoire optimisées ne prennent pas en charge les transactions entre bases de données. Vous ne pouvez pas accéder à une autre base de données à partir de la même transaction ou de la même requête qui accède également à une table mémoire optimisée. Vous ne pouvez pas facilement copier les données d'une table d'une base de données, à une table mémoire optimisée d'une autre base de données.
Les variables de table ne sont pas transactionnelles. Par conséquent, les variables des tables mémoire optimisées peuvent être utilisées dans des requêtes de bases de données croisées, et peuvent donc faciliter le déplacement des données d'une base de données dans des tables mémoire optimisées dans une autre base de données. Vous pouvez utiliser deux transactions. Dans la première transaction, insérez les données de la table distante dans la variable. Dans la seconde transaction, insérez les données dans la table mémoire optimisée locale depuis la variable. Pour plus d’informations sur les variables de table mémoire optimisée, consultez Table temporaire et variable de table plus rapides à l’aide de l’optimisation de la mémoire.
Exemple
Cet exemple illustre une méthode pour transférer des données d’une base de données à une table optimisée en mémoire dans une autre base de données.
Créez des objets de test. Exécutez l’instruction Transact-SQL suivant dans SQL Server Management Studio.
USE master; GO SET NOCOUNT ON; -- Create simple database CREATE DATABASE SourceDatabase; ALTER DATABASE SourceDatabase SET RECOVERY SIMPLE; GO -- Create a table and insert a few records USE SourceDatabase; CREATE TABLE SourceDatabase.[dbo].[SourceTable] ( [ID] [int] PRIMARY KEY CLUSTERED, [FirstName] nvarchar(8) ); INSERT [SourceDatabase].[dbo].[SourceTable] VALUES (1, N'Bob'), (2, N'Susan'); GO -- Create a database with a MEMORY_OPTIMIZED_DATA filegroup CREATE DATABASE DestinationDatabase ON PRIMARY ( NAME = N'DestinationDatabase_Data', FILENAME = N'D:\DATA\DestinationDatabase_Data.mdf', SIZE = 8MB), FILEGROUP [DestinationDatabase_mod] CONTAINS MEMORY_OPTIMIZED_DATA DEFAULT ( NAME = N'DestinationDatabase_mod', FILENAME = N'D:\DATA\DestinationDatabase_mod', MAXSIZE = UNLIMITED) LOG ON ( NAME = N'DestinationDatabase_Log', FILENAME = N'D:\LOG\DestinationDatabase_Log.ldf', SIZE = 8MB); ALTER DATABASE DestinationDatabase SET RECOVERY SIMPLE; GO USE DestinationDatabase; GO -- Create a memory-optimized table CREATE TABLE [dbo].[DestTable_InMem] ( [ID] [int] PRIMARY KEY NONCLUSTERED, [FirstName] nvarchar(8) ) WITH ( MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA ); GO
Essayez les requêtes de bases de données croisées. Exécutez l’instruction Transact-SQL suivant dans SQL Server Management Studio.
INSERT [DestinationDatabase].[dbo].[DestTable_InMem] SELECT * FROM [SourceDatabase].[dbo].[SourceTable]
Vous devriez obtenir le message d’erreur suivant :
Msg 41317, Niveau 16, État 5
Une transaction utilisateur qui accède à des tables optimisées en mémoire ou à des modules compilés en mode natif ne peut pas accéder à plus d’une base de données utilisateur ou à des bases de données model et msdb, et ne peut pas écrire dans une base de données MASTER.Créer un type de table optimisée en mémoire. Exécutez l’instruction Transact-SQL suivant dans SQL Server Management Studio.
USE DestinationDatabase; GO CREATE TYPE [dbo].[MemoryType] AS TABLE ( [ID] [int] PRIMARY KEY NONCLUSTERED, [FirstName] nvarchar(8) ) WITH (MEMORY_OPTIMIZED = ON); GO
Réessayez la requête de bases de données croisées. Cette fois, les données source seront tout d’abord transférées à une variable de table optimisée en mémoire. Ensuite, les données à partir de la variable de table seront transférées vers la table optimisée en mémoire.
-- Declare table variable utilizing the newly created type - MemoryType DECLARE @InMem dbo.MemoryType; -- Populate table variable INSERT @InMem SELECT * FROM SourceDatabase.[dbo].[SourceTable]; -- Populate the destination memory-optimized table INSERT [DestinationDatabase].[dbo].[DestTable_InMem] SELECT * FROM @InMem; GO