1

我正在尝试让 Enterprise Library 5.0 日志记录到 Azure SQL。我认为我的 .config 还可以,但我正在尝试使用 EntLib 5.0 ( \EntLib50Src\Blocks\Logging\Src\DatabaseTraceListener\Scripts\)附带的脚本设置 SQL 表和存储过程

由于脚本很长,我已将其上传到此处(与有问题的嵌入相比)

不幸的是,该脚本是 EntLib 团队在 2005 年编写的,从未更新或维护。随后,许多命令不适用于 Azure SQL 甚至 SQL Server 2012。我在 SQL Server 2012 上遇到的错误是

Could not find stored procedure 'sp_dboption'.

是否有用于为 Azure SQL 设置表和存储过程的更新脚本?此外,如果您正在登录 Azure SQL,将不胜感激您分享您的脚本。

4

2 回答 2

1

可能正式正确的答案是从Microsoft Enterprise Library 5.0 Integration Pack for Windows Azure下载 EnterpriseLibraryIntegrationPack-WindowsAzure-sqlscripts.exe 。解压后,它包含企业库所需的所有 SQL 脚本,这些脚本由 Patterns & Practices 团队修改以使用 SQL Azure。

我将在下面留下我的原始答案,因为它与提供的脚本几乎相同。

为数据库日志记录提供的脚本适用于 SQL Server。 SQL Azure 不支持 sp_dboption 存储过程

基本上,您真正需要的只是 Category、CategoryLog 和 Log 表以及 AddCategory、WriteLog 和 InsertCategoryLog 存储过程。

首先创建 Logging 数据库(使用门户或通过运行脚本):

CREATE DATABASE [Logging]
(MAXSIZE=1GB,
EDITION='web');
GO

如果您删除不受支持的语句,脚本将如下所示:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[Category]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[Category](
    [CategoryID] [int] IDENTITY(1,1) NOT NULL,
    [CategoryName] [nvarchar](64) NOT NULL,
 CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED 
(
    [CategoryID] ASC
) 
) 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[CategoryLog]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[CategoryLog](
    [CategoryLogID] [int] IDENTITY(1,1) NOT NULL,
    [CategoryID] [int] NOT NULL,
    [LogID] [int] NOT NULL,
 CONSTRAINT [PK_CategoryLog] PRIMARY KEY CLUSTERED 
(
    [CategoryLogID] ASC
) 
) 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[Log]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[Log](
    [LogID] [int] IDENTITY(1,1) NOT NULL,
    [EventID] [int] NULL,
    [Priority] [int] NOT NULL,
    [Severity] [nvarchar](32) NOT NULL,
    [Title] [nvarchar](256) NOT NULL,
    [Timestamp] [datetime] NOT NULL,
    [MachineName] [nvarchar](32) NOT NULL,
    [AppDomainName] [nvarchar](512) NOT NULL,
    [ProcessID] [nvarchar](256) NOT NULL,
    [ProcessName] [nvarchar](512) NOT NULL,
    [ThreadName] [nvarchar](512) NULL,
    [Win32ThreadId] [nvarchar](128) NULL,
    [Message] [nvarchar](1500) NULL,
    [FormattedMessage] [ntext] NULL,
 CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
(
    [LogID] ASC
) 
) 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[InsertCategoryLog]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE InsertCategoryLog
    @CategoryID INT,
    @LogID INT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @CatLogID INT
    SELECT @CatLogID FROM CategoryLog WHERE CategoryID=@CategoryID and LogID = @LogID
    IF @CatLogID IS NULL
    BEGIN
        INSERT INTO CategoryLog (CategoryID, LogID) VALUES(@CategoryID, @LogID)
        RETURN @@IDENTITY
    END
    ELSE RETURN @CatLogID
END
' 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[AddCategory]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'

CREATE PROCEDURE [dbo].[AddCategory]
    -- Add the parameters for the function here
    @CategoryName nvarchar(64),
    @LogID int
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @CatID INT
    SELECT @CatID = CategoryID FROM Category WHERE CategoryName = @CategoryName
    IF @CatID IS NULL
    BEGIN
        INSERT INTO Category (CategoryName) VALUES(@CategoryName)
        SELECT @CatID = @@IDENTITY
    END

    EXEC InsertCategoryLog @CatID, @LogID 

    RETURN @CatID
END

' 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[ClearLogs]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE ClearLogs
AS
BEGIN
    SET NOCOUNT ON;

    DELETE FROM CategoryLog
    DELETE FROM [Log]
    DELETE FROM Category
END
' 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[WriteLog]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'



/****** Object:  Stored Procedure dbo.WriteLog    Script Date: 10/1/2004 3:16:36 PM ******/

CREATE PROCEDURE [dbo].[WriteLog]
(
    @EventID int, 
    @Priority int, 
    @Severity nvarchar(32), 
    @Title nvarchar(256), 
    @Timestamp datetime,
    @MachineName nvarchar(32), 
    @AppDomainName nvarchar(512),
    @ProcessID nvarchar(256),
    @ProcessName nvarchar(512),
    @ThreadName nvarchar(512),
    @Win32ThreadId nvarchar(128),
    @Message nvarchar(1500),
    @FormattedMessage ntext,
    @LogId int OUTPUT
)
AS 

    INSERT INTO [Log] (
        EventID,
        Priority,
        Severity,
        Title,
        [Timestamp],
        MachineName,
        AppDomainName,
        ProcessID,
        ProcessName,
        ThreadName,
        Win32ThreadId,
        Message,
        FormattedMessage
    )
    VALUES (
        @EventID, 
        @Priority, 
        @Severity, 
        @Title, 
        @Timestamp,
        @MachineName, 
        @AppDomainName,
        @ProcessID,
        @ProcessName,
        @ThreadName,
        @Win32ThreadId,
        @Message,
        @FormattedMessage)

    SET @LogID = @@IDENTITY
    RETURN @LogID



' 
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'FK_CategoryLog_Category') AND parent_obj = OBJECT_ID(N'[dbo].[CategoryLog]'))
ALTER TABLE [dbo].[CategoryLog]  WITH CHECK ADD  CONSTRAINT [FK_CategoryLog_Category] FOREIGN KEY(  [CategoryID])
REFERENCES [dbo].[Category] (   [CategoryID])
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'FK_CategoryLog_Log') AND parent_obj = OBJECT_ID(N'[dbo].[CategoryLog]'))
ALTER TABLE [dbo].[CategoryLog]  WITH CHECK ADD  CONSTRAINT [FK_CategoryLog_Log] FOREIGN KEY(   [LogID])
REFERENCES [dbo].[Log] (    [LogID])
GO

SET QUOTED_IDENTIFIER ON 
SET ARITHABORT ON 
SET CONCAT_NULL_YIELDS_NULL ON 
SET ANSI_NULLS ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET NUMERIC_ROUNDABORT OFF 
go

DECLARE @bErrors as bit

BEGIN TRANSACTION
SET @bErrors = 0

CREATE NONCLUSTERED INDEX [ixCategoryLog] ON [dbo].[CategoryLog] ([LogID] ASC, [CategoryID] ASC )
IF( @@error <> 0 ) SET @bErrors = 1

IF( @bErrors = 0 )
  COMMIT TRANSACTION
ELSE
  ROLLBACK TRANSACTION

然后,我按照使用 SQL Server Management Studio 管理 Windows Azure SQL 数据库的方式使用 SSMS来运行脚本。

于 2012-12-27T05:45:39.303 回答
0

我最终做的是:

  1. 从这里下载 Microsoft SQL Server Data Tools。如果您管理任何 Azure SQL 数据库,这是必须具备的。Schema 比较和合并更改以及能够将其余代码推入 GIT 非常棒。无论如何,回到主题......

  2. 在我的解决方案中添加了“SQL Server 数据库项目”。

  3. “右键单击数据库项目 => 属性 => 将目标设置为“Windows Azure SQL 数据库”。还在同一部分的输出类型区域中选中“创建脚本”。

  4. 右键单击数据库项目 => 导入 SQL => 将 2005 年的 EntLib5.0 脚本传递给它。这会将脚本分解为每个表和每个存储过程的单独 .SQL 文件。

  5. Visual Studio 抱怨无法分解整个脚本(主要是存储过程)。它能够导入的内容在导入的脚本中被注释掉(很好,防止重复)

  6. 我手动添加了存储的过程。添加新项目 => 存储过程 => 使用 2005 脚本中的名称 => 复制粘贴相同的旧 SQL 代码。对 2005 SQL 脚本文件中的所有 4 个 SP 执行此操作

  7. “构建”项目 => 没有错误

  8. 右键单击数据库项目 => 架构比较 => 指向您的 azure 数据库

  9. 点击更新

单击更新将自动创建 SQL 脚本,并将针对 Azure 数据库运行它。生成的脚本如下。由于某种原因,相同的脚本无法在 SQL Server 2012 Management Studio 中正常运行(是的,即使在 SQL CMD 模式下)。然而,即使从 VS2012 数据项目(上图)运行它也能正常工作。

/*
Deployment script for test

This code was generated by a tool.
Changes to this file may cause incorrect behavior and will be lost if
the code is regenerated.
*/

GO
SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;

SET NUMERIC_ROUNDABORT OFF;


GO
:setvar DatabaseName "Logging"
:setvar DefaultFilePrefix "Logging"
:setvar DefaultDataPath ""
:setvar DefaultLogPath ""

GO
:on error exit
GO
/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following:
SET NOEXEC OFF; 
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
    BEGIN
        PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
        SET NOEXEC ON;
    END


GO
USE [$(DatabaseName)];


GO
PRINT N'Creating [dbo].[Category]...';


GO
CREATE TABLE [dbo].[Category] (
    [CategoryID]   INT           IDENTITY (1, 1) NOT NULL,
    [CategoryName] NVARCHAR (64) NOT NULL,
    CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED ([CategoryID] ASC)
);


GO
PRINT N'Creating [dbo].[CategoryLog]...';


GO
CREATE TABLE [dbo].[CategoryLog] (
    [CategoryLogID] INT IDENTITY (1, 1) NOT NULL,
    [CategoryID]    INT NOT NULL,
    [LogID]         INT NOT NULL,
    CONSTRAINT [PK_CategoryLog] PRIMARY KEY CLUSTERED ([CategoryLogID] ASC)
);


GO
PRINT N'Creating [dbo].[CategoryLog].[ixCategoryLog]...';


GO
CREATE NONCLUSTERED INDEX [ixCategoryLog]
    ON [dbo].[CategoryLog]([LogID] ASC, [CategoryID] ASC);


GO
PRINT N'Creating [dbo].[Log]...';


GO
CREATE TABLE [dbo].[Log] (
    [LogID]            INT             IDENTITY (1, 1) NOT NULL,
    [EventID]          INT             NULL,
    [Priority]         INT             NOT NULL,
    [Severity]         NVARCHAR (32)   NOT NULL,
    [Title]            NVARCHAR (256)  NOT NULL,
    [Timestamp]        DATETIME        NOT NULL,
    [MachineName]      NVARCHAR (32)   NOT NULL,
    [AppDomainName]    NVARCHAR (512)  NOT NULL,
    [ProcessID]        NVARCHAR (256)  NOT NULL,
    [ProcessName]      NVARCHAR (512)  NOT NULL,
    [ThreadName]       NVARCHAR (512)  NULL,
    [Win32ThreadId]    NVARCHAR (128)  NULL,
    [Message]          NVARCHAR (1500) NULL,
    [FormattedMessage] NTEXT           NULL,
    CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED ([LogID] ASC)
);


GO
PRINT N'Creating FK_CategoryLog_Category...';


GO
ALTER TABLE [dbo].[CategoryLog] WITH NOCHECK
    ADD CONSTRAINT [FK_CategoryLog_Category] FOREIGN KEY ([CategoryID]) REFERENCES [dbo].[Category] ([CategoryID]);


GO
PRINT N'Creating FK_CategoryLog_Log...';


GO
ALTER TABLE [dbo].[CategoryLog] WITH NOCHECK
    ADD CONSTRAINT [FK_CategoryLog_Log] FOREIGN KEY ([LogID]) REFERENCES [dbo].[Log] ([LogID]);


GO
PRINT N'Creating [dbo].[ClearLogs]...';


GO
CREATE PROCEDURE ClearLogs
AS
BEGIN
    SET NOCOUNT ON;

    DELETE FROM CategoryLog
    DELETE FROM [Log]
    DELETE FROM Category
END
GO
PRINT N'Creating [dbo].[InsertCategoryLog]...';


GO
CREATE PROCEDURE InsertCategoryLog
    @CategoryID INT,
    @LogID INT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @CatLogID INT
    SELECT @CatLogID FROM CategoryLog WHERE CategoryID=@CategoryID and LogID = @LogID
    IF @CatLogID IS NULL
    BEGIN
        INSERT INTO CategoryLog (CategoryID, LogID) VALUES(@CategoryID, @LogID)
        RETURN @@IDENTITY
    END
    ELSE RETURN @CatLogID
END
GO
PRINT N'Creating [dbo].[WriteLog]...';


GO
CREATE PROCEDURE [dbo].[WriteLog]
(
    @EventID int, 
    @Priority int, 
    @Severity nvarchar(32), 
    @Title nvarchar(256), 
    @Timestamp datetime,
    @MachineName nvarchar(32), 
    @AppDomainName nvarchar(512),
    @ProcessID nvarchar(256),
    @ProcessName nvarchar(512),
    @ThreadName nvarchar(512),
    @Win32ThreadId nvarchar(128),
    @Message nvarchar(1500),
    @FormattedMessage ntext,
    @LogID int OUTPUT
)
AS 

    INSERT INTO [Log] (
        EventID,
        Priority,
        Severity,
        Title,
        [Timestamp],
        MachineName,
        AppDomainName,
        ProcessID,
        ProcessName,
        ThreadName,
        Win32ThreadId,
        Message,
        FormattedMessage
    )
    VALUES (
        @EventID, 
        @Priority, 
        @Severity, 
        @Title, 
        @Timestamp,
        @MachineName, 
        @AppDomainName,
        @ProcessID,
        @ProcessName,
        @ThreadName,
        @Win32ThreadId,
        @Message,
        @FormattedMessage)

SET @LogID = @@IDENTITY
RETURN @LogID
GO
PRINT N'Creating [dbo].[AddCategory]...';


GO
CREATE PROCEDURE [dbo].[AddCategory]
    -- Add the parameters for the function here
    @CategoryName nvarchar(64),
    @LogID int
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @CatID INT
    SELECT @CatID = CategoryID FROM Category WHERE CategoryName = @CategoryName
    IF @CatID IS NULL
    BEGIN
        INSERT INTO Category (CategoryName) VALUES(@CategoryName)
        SELECT @CatID = @@IDENTITY
    END

    EXEC InsertCategoryLog @CatID, @LogID 

    RETURN @CatID
END
GO
于 2012-12-27T05:57:22.590 回答