我收到“错误消息512,级别16,状态1,行1子查询返回超过1的值”

时间:2014-01-28 20:29:45

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

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

  

Msg 512,Level 16,State 1,Line 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

2 个答案:

答案 0 :(得分:0)

尝试使用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

答案 1 :(得分:0)

我用它来识别群集中每台服务器上的高可用性数据库是主要的,辅助的,只读的辅助数据库。我将使用它来修改我的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