sql-server - SQL SERVER - 通过 SQLCMD 和 MSSQL 运行 SQL 脚本时相同的代码不同的结果

标签 sql-server xpath quoted-identifier

我有这个奇怪的问题,相同的脚本有不同的结果。下面是我的代码:

--Create table ExtractForCustomerLoyalty--------------------------------------------------------------------
--This contains the customer extract records and is used by CustomerLoyaltyExporter batch job.
--Version 1 - 8/14/2018
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ExtractForCustomerLoyalty')
BEGIN
    Print 'Creating [dbo].[ExtractForCustomerLoyalty] table...'

    CREATE TABLE [dbo].[ExtractForCustomerLoyalty](
        [rowID] [int] NOT NULL,
        [sequenceCount] [int] NOT NULL,
        [extractTime] [datetime] NOT NULL,
        [extractData] [varchar](8000) NOT NULL,
        [exported] [varchar](1) NOT NULL DEFAULT ('N')
    ) ON [PRIMARY]
END
GO


--Create trigger customer_extract---------------------------------------------------------------------------
--This trigger is used to create customer extract records
--Version 1 - 8/14/2018
IF EXISTS (SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'['+OBJECT_SCHEMA_NAME(object_id)+N'].[customer_extract]') AND [type] = 'TR')
BEGIN
    Print 'Dropping [dbo].[customer_extract] Trigger'
    DROP TRIGGER [dbo].[customer_extract];
END;
GO

CREATE TRIGGER [dbo].[customer_extract] on [CCSV4].[dbo].[ExtractForStandardCustomer]
AFTER INSERT
AS
    SET ANSI_NULLS ON
    SET ANSI_PADDING ON
    SET ANSI_WARNINGS ON
    SET ARITHABORT ON
    SET CONCAT_NULL_YIELDS_NULL ON
    SET QUOTED_IDENTIFIER ON

    --Just in case we need to deactivate trigger
    DECLARE @Cinfo VARBINARY(128)  
    SELECT @Cinfo = Context_Info()  
    IF @Cinfo = 0x55555  
        RETURN

    --Declaration
    DECLARE @rowID int
    DECLARE @dataXML XML
    DECLARE @data VARCHAR(MAX) = ''

    -- Get the complete extractData xml from ExtractForStandardCustomer table
    SET @rowID = (select rowID from inserted)
    SELECT @data = @data + extractData FROM ExtractForStandardCustomer where rowID = @rowID order by sequenceCount
    SET @dataXML = TRY_CAST(@data as XML)

    IF @dataXML IS NULL
        RETURN

    -- Check the CustomerUpdate type (Create / Update / Delete)
    IF (@dataXML.exist('(/CustomerExtract/Change)') = 1)
        -- Customer Update
        INSERT INTO [dbo].[ExtractForCustomerLoyalty](rowID, sequenceCount, extractTime, extractData)
        SELECT i.rowID, i.sequenceCount, i.extractTime,
            '' + '|' +
            '' + '|' +
            ISNULL(@dataXML.value('(//After/Customer/Loyalty/LoyaltyID)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//After/Customer/Loyalty/JoinLocation)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//After/Customer/Loyalty/JoinDate)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//After/Customer/Loyalty/FirstPurchaseDate)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//After/Customer/Loyalty/FirstPurchaseLocation)[1]', 'VARCHAR(8000)'),'') + '|'
            ---More here
        FROM inserted i
    ELSE
        BEGIN
        --Customer Create / Delete
        INSERT INTO [dbo].[ExtractForCustomerLoyalty](rowID, sequenceCount, extractTime, extractData)
        SELECT top 1 i.rowID, i.sequenceCount, i.extractTime,
            '' + '|' +  --CUSTOMER_ID (NULL for now)
            '' + '|' +  --HOUSEHOLD_ID (NULL for now)
            ISNULL(@dataXML.value('(//Customer/Loyalty/LoyaltyID)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//Customer/Loyalty/JoinLocation)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//Customer/Loyalty/JoinDate)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//Customer/Loyalty/FirstPurchaseDate)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//Customer/Loyalty/FirstPurchaseLocation)[1]', 'VARCHAR(8000)'),'') + '|' +
            ISNULL(@dataXML.value('(//Customer/Name/First)[1]', 'VARCHAR(8000)'),'') + '|'
            --More here

        FROM inserted i
        END
GO

当我使用 SQL Server Management Studio 2014 UI 运行它时,当我在 ExtractForStandardCustomer 表上插入一些东西时,触发器会正常执行。它使用所需的记录填充 ExtractForCustomerLoyalty 表...

但是,当我尝试通过 cmd 运行相同的脚本时:
sqlcmd -E -d testDB -i TESTSCRIPT.sql > TESTSCRIPT.log

它抛出这个错误:
 com.microsoft.sqlserver.jdbc.SQLServerException: CONDITIONAL failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.

最佳答案

不同的工具和库有不同的默认设置。

来自 SET QUOTED_IDENTIFIER :

The SQL Server Native Client ODBC driver and SQL Server Native Client OLE DB Provider for SQL Server automatically set QUOTED_IDENTIFIER to ON when connecting. This can be configured in ODBC data sources, in ODBC connection attributes, or OLE DB connection properties. The default for SET QUOTED_IDENTIFIER is OFF for connections from DB-Library applications.



如果您不乐意接受默认值,或者(如此处)希望无论使用什么默认值都能够以可预测的方式运行脚本,请明确设置您需要的选项。

另外,请特别注意 QUOTED_IDENTIFIERANSI_NULLS在定义模块(例如触发器、存储过程等)时捕获。您要确保在任何特定模块定义之外的连接上应用这些设置。

始终指定 -I 是一个很好的(也许是最好的)做法。执行SQLCMD时的命令行参数这样QUOTED_IDENTIFIER默认开启。 SQLCMD 中的设置默认关闭为了向后兼容。

关于sql-server - SQL SERVER - 通过 SQLCMD 和 MSSQL 运行 SQL 脚本时相同的代码不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51871969/

相关文章:

c# - SQL 插入语句语法

java - Flipkart.com 价格 slider xpath

java - 使用 XPath 查询 oracle 数据库时,如何返回值列表而不是字符串?

ruby - 获取标签名称的 xpath 语法是什么?

postgresql - 为什么 PostgreSQL 不喜欢大写的表名?

sql-server - 如何查询数据库区域性 (SQL Server 2005)?

c# - EF : When executing a command, 参数必须完全是数据库参数或值

oracle - 如何使用 oracle 创建一个带有小字符的表?

mysql - 如何获取 SQL 文件并将其导入到 Rails Active Record 基本连接中?

postgresql - Postgres : relation does not exist error when table exists on public schema