sql 服务器 2014 上的跨数据库查询
cross database query on sql server 2014
我有一个内存优化的数据库table。我想将此 table 存档在另一个数据库中。我想写一个存储过程来做到这一点。
我在 1 and 2 下面的示例中成功实现了,但是在这些示例中,第一个数据库不在内存中,第二个数据库在内存中。
在我的例子中,第一个数据库在内存中,第二个可以在内存中也可以不在内存中。
这是我的代码:
1- 我的 table :
USE [TestReport]
GO
/****** Object: Table [dbo].[Report] Script Date: 1/22/2018 4:40:04 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Report]
(
[ReportID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[Year] [int] NOT NULL,
[DayOfYear] [int] NOT NULL,
[ProductType] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[ApplicationID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[TotalSize] [bigint] NOT NULL DEFAULT ((0)),
[TotalCount] [bigint] NOT NULL DEFAULT ((0)),
[LastReportTimeSpan] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NULL,
INDEX [idx] NONCLUSTERED HASH
(
[ReportID],
[DayOfYear]
)WITH ( BUCKET_COUNT = 131072),
CONSTRAINT [pk] PRIMARY KEY NONCLUSTERED HASH
(
[ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID]
)WITH ( BUCKET_COUNT = 131072)
)WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_AND_DATA )
GO
2-简单存储过程
CREATE PROCEDURE [dbo].[ArchiveReport]
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS BEGIN ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)
BEGIN
DECLARE @currentdate DATETIME2;
SET @currentdate = GETDATE();
declare @maintainDay INT = 5
INSERT TestReportArchive.[dbo].Report
SELECT [ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID],
[TotalSize],
[TotalCount],
[LastReportTimeSpan]
FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
DELETE FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
END;
END
3-简单存储过程错误
Msg 4512, Level 16, State 3, Procedure ArchiveReport, Line 12
Cannot schema bind procedure 'dbo.ArchiveReport' because name 'TestReportArchive.dbo.Report' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
TestReportArchive is my destination database
USE [TestReport]
GO
/****** Object: UserDefinedTableType [dbo].[MemoryType] Script Date: 1/22/2018 4:35:14 PM ******/
CREATE TYPE [dbo].[MemoryType] AS TABLE(
[ReportID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[Year] [int] NOT NULL,
[DayOfYear] [int] NOT NULL,
[ProductType] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[ApplicationID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[TotalSize] [bigint] NOT NULL,
[TotalCount] [bigint] NOT NULL,
[LastReportTimeSpan] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NULL,
INDEX [idx] NONCLUSTERED HASH
(
[ReportID],
[DayOfYear]
)WITH ( BUCKET_COUNT = 131072)
)
WITH ( MEMORY_OPTIMIZED = ON )
GO
5- 带有 table 变量的存储过程
CREATE PROCEDURE [dbo].[ArchiveReport]
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS BEGIN ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)
BEGIN
DECLARE @currentdate DATETIME2;
SET @currentdate = GETDATE();
declare @maintainDay INT = 5
DECLARE @InMem [dbo].[MemoryType];
INSERT @InMem
SELECT [ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID],
[TotalSize],
[TotalCount],
[LastReportTimeSpan]
FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
INSERT TestReportArchive.[dbo].[Report]
SELECT [ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID],
[TotalSize],
[TotalCount],
[LastReportTimeSpan]
FROM @InMem
DELETE FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
END;
END
6- 来自 5 个存储过程的错误
Msg 4512, Level 16, State 3, Procedure ArchiveReport, Line 25
Cannot schema bind procedure 'dbo.ArchiveReport' because name 'TestReportArchive.dbo.Report' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
TestReportArchive is my destination database
不支持涉及内存优化表的跨数据库查询。
Unsupported SQL Server Features for In-Memory OLTP
A query cannot access other databases if the query uses either a
memory-optimized table or a natively compiled stored procedure. This
restriction applies to transactions as well as to queries.
最终,我在 testReport(第一个数据库)上创建了一个非内存优化的 table (ReportTemp),并更改存储过程以将数据从 Report Table 插入到 ReportTemp Table 在第一个数据库中。然后我再写一个 SP 将数据移动到存档数据库。
我有一个内存优化的数据库table。我想将此 table 存档在另一个数据库中。我想写一个存储过程来做到这一点。
我在 1 and 2 下面的示例中成功实现了,但是在这些示例中,第一个数据库不在内存中,第二个数据库在内存中。 在我的例子中,第一个数据库在内存中,第二个可以在内存中也可以不在内存中。
这是我的代码:
1- 我的 table :
USE [TestReport]
GO
/****** Object: Table [dbo].[Report] Script Date: 1/22/2018 4:40:04 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Report]
(
[ReportID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[Year] [int] NOT NULL,
[DayOfYear] [int] NOT NULL,
[ProductType] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[ApplicationID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[TotalSize] [bigint] NOT NULL DEFAULT ((0)),
[TotalCount] [bigint] NOT NULL DEFAULT ((0)),
[LastReportTimeSpan] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NULL,
INDEX [idx] NONCLUSTERED HASH
(
[ReportID],
[DayOfYear]
)WITH ( BUCKET_COUNT = 131072),
CONSTRAINT [pk] PRIMARY KEY NONCLUSTERED HASH
(
[ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID]
)WITH ( BUCKET_COUNT = 131072)
)WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_AND_DATA )
GO
2-简单存储过程
CREATE PROCEDURE [dbo].[ArchiveReport]
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS BEGIN ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)
BEGIN
DECLARE @currentdate DATETIME2;
SET @currentdate = GETDATE();
declare @maintainDay INT = 5
INSERT TestReportArchive.[dbo].Report
SELECT [ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID],
[TotalSize],
[TotalCount],
[LastReportTimeSpan]
FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
DELETE FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
END;
END
3-简单存储过程错误
Msg 4512, Level 16, State 3, Procedure ArchiveReport, Line 12
Cannot schema bind procedure 'dbo.ArchiveReport' because name 'TestReportArchive.dbo.Report' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
TestReportArchive is my destination database
USE [TestReport]
GO
/****** Object: UserDefinedTableType [dbo].[MemoryType] Script Date: 1/22/2018 4:35:14 PM ******/
CREATE TYPE [dbo].[MemoryType] AS TABLE(
[ReportID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[Year] [int] NOT NULL,
[DayOfYear] [int] NOT NULL,
[ProductType] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[ApplicationID] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NOT NULL,
[TotalSize] [bigint] NOT NULL,
[TotalCount] [bigint] NOT NULL,
[LastReportTimeSpan] [nvarchar](50) COLLATE Latin1_General_100_BIN2 NULL,
INDEX [idx] NONCLUSTERED HASH
(
[ReportID],
[DayOfYear]
)WITH ( BUCKET_COUNT = 131072)
)
WITH ( MEMORY_OPTIMIZED = ON )
GO
5- 带有 table 变量的存储过程
CREATE PROCEDURE [dbo].[ArchiveReport]
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS BEGIN ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)
BEGIN
DECLARE @currentdate DATETIME2;
SET @currentdate = GETDATE();
declare @maintainDay INT = 5
DECLARE @InMem [dbo].[MemoryType];
INSERT @InMem
SELECT [ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID],
[TotalSize],
[TotalCount],
[LastReportTimeSpan]
FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
INSERT TestReportArchive.[dbo].[Report]
SELECT [ReportID],
[Year],
[DayOfYear],
[ProductType],
[ApplicationID],
[TotalSize],
[TotalCount],
[LastReportTimeSpan]
FROM @InMem
DELETE FROM [dbo].[Report]
WHERE DATEADD(day, [DayOfYear] + @maintainDay, DATEADD(YEAR, [Year] - 1900, 0)) > @currentdate;
END;
END
6- 来自 5 个存储过程的错误
Msg 4512, Level 16, State 3, Procedure ArchiveReport, Line 25
Cannot schema bind procedure 'dbo.ArchiveReport' because name 'TestReportArchive.dbo.Report' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
TestReportArchive is my destination database
不支持涉及内存优化表的跨数据库查询。
Unsupported SQL Server Features for In-Memory OLTP
A query cannot access other databases if the query uses either a memory-optimized table or a natively compiled stored procedure. This restriction applies to transactions as well as to queries.
最终,我在 testReport(第一个数据库)上创建了一个非内存优化的 table (ReportTemp),并更改存储过程以将数据从 Report Table 插入到 ReportTemp Table 在第一个数据库中。然后我再写一个 SP 将数据移动到存档数据库。