【问题标题】:I'm getting "error Msg 512, Level 16, State 1, Line 1 Subquery returned more than 1 value"我收到“错误消息 512,级别 16,状态 1,第 1 行子查询返回超过 1 个值”
【发布时间】:2014-01-28 20:29:45
【问题描述】:

在尝试确定特定集群上高可用性数据库的状态时,我收到了标题的错误消息。

消息 512,第 16 级,状态 1,第 1 行
子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的

这是我的代码的一部分。我需要能够利用两个 select 语句的结果,然后在两者都满足时分配 @HadrRole

IF ((SELECT ars.role
     FROM sys.dm_hadr_availability_replica_states ars
     INNER JOIN sys.databases dbs
     ON ars.replica_id = dbs.replica_id
     WHERE dbs.name = @DatabaseName) = 2 AND (SELECT secondary_role_allow_connections_desc
     FROM sys.availability_replicas) ='ALL')
SET @HadrRole = 3

【问题讨论】:

  • 那么,这个选择返回的值不止一个吗?

标签: sql-server tsql cluster-computing high-availability


【解决方案1】:

尝试使用EXISTS子查询:

IF EXISTS 
    (
        SELECT *
        FROM sys.dm_hadr_availability_replica_states ars
        INNER JOIN sys.databases dbs
        ON ars.replica_id = dbs.replica_id
        WHERE dbs.name = @DatabaseName AND ars.role = 2
    ) AND 
    EXISTS 
    (
        SELECT  *
        FROM    sys.availability_replicas
        WHERE   secondary_role_allow_connections_desc = 'ALL'
    )
SET @HadrRole = 3

注意:您可以这样使用SET 语句:

SET @HadrRole = 
    CASE 
    WHEN EXISTS 
        (
            SELECT *
            FROM sys.dm_hadr_availability_replica_states ars
            INNER JOIN sys.databases dbs
            ON ars.replica_id = dbs.replica_id
            WHERE dbs.name = @DatabaseName AND ars.role = 2
        ) 
        AND EXISTS 
        (
            SELECT  *
            FROM    sys.availability_replicas
            WHERE   secondary_role_allow_connections_desc = 'ALL'
        )
    THEN 3 
    ELSE @HadrRole 
    END

【讨论】:

    【解决方案2】:

    我用它来确定集群中每台服务器上的高可用性数据库是主数据库、辅助数据库还是只读辅助数据库。我将使用它来修改我的 SQL 代理作业,以便它们在集群中的正确服务器上运行(根据作业只读辅助或主服务器。感谢您的回复!我希望这对其他人有所帮助。

    USE [msdb]
    GO
    
    /****** Object:  UserDefinedFunction [dbo].[RG_fn_HA_isPrimaryReplica_isSecondayReadable]    Script Date: 1/27/2014 4:31:39 PM ******/
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    IF object_id(N'RG_fn_HA_isPrimaryReplica_isSecondayReadable', 'FN') IS NOT NULL
        DROP FUNCTION RG_fn_HA_isPrimaryReplica_isSecondayReadable
        GO
    CREATE FUNCTION [dbo].[RG_fn_HA_isPrimaryReplica_isSecondayReadable] (@DatabaseName SYSNAME)
    RETURNS TINYINT
    WITH EXECUTE AS CALLER
    AS
    /********************************************************************
      File Name:    RG_fn_HA_isPrimaryReplica_isSecondayReadable.sql
      Applies to:   SQL Server 2012
      Purpose:      To return either 0, 1, or 2 based on whether this
                    @DatabaseName is a primary or secondary replica.
      Parameters:   @DatabaseName - The name of the database to check.
      Returns:      0 = Resolving
                    1 = Primary
                    2 = Secondary 
                    3 = Readable Secondary
      Author:       Matthew Joyce
      Version:      1.0.0 - 01/28/2014
    ********************************************************************/
    BEGIN
        DECLARE @HadrRole TINYINT
        -- Return role status from sys.dm_hadr_availability_replica_states
        IF (SELECT ars.role
            FROM sys.dm_hadr_availability_replica_states ars
            INNER JOIN sys.databases dbs
            ON ars.replica_id = dbs.replica_id
            WHERE dbs.name = @DatabaseName) = 1
            SET @HadrRole = 1
    ELSE
        -- @DatabaseName exists but does not belong to an AG so return 1
        --  IF @HadrRole IS NULL
            --SET @HadrRole = 1
    --ELSE 
        --Return 2 if secondary but not readable
         IF (SELECT ars.role
            FROM sys.dm_hadr_availability_replica_states ars
            INNER JOIN sys.databases dbs
            ON ars.replica_id = dbs.replica_id
            WHERE dbs.name = @DatabaseName) = 2 AND (SELECT secondary_role_allow_connections_desc
            FROM sys.availability_replicas
            where replica_server_name =(select @@ServerName)) <>'ALL'
    SET @HadrRole = 2
    ELSE 
         IF (SELECT ars.role
            FROM sys.dm_hadr_availability_replica_states ars
            INNER JOIN sys.databases dbs
            ON ars.replica_id = dbs.replica_id
            WHERE dbs.name = @DatabaseName) = 2 AND (SELECT secondary_role_allow_connections_desc
            FROM sys.availability_replicas
            where replica_server_name =(select @@ServerName)) ='ALL'
    SET @HadrRole = 3
            RETURN @HadrRole;
    END;
    GO
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      • 2016-02-07
      相关资源
      最近更新 更多