从sssms执行时,如果字段不为null,则ado.net数据读取器中sys.check_constraints的定义列为null

时间:2019-07-10 19:11:25

标签: c# sql-server ado.net

我试图编写一个C#程序(.Net核心2.1),以从ms sql服务器数据库中读取给定表的所有检查约束。我正在使用sys.check_constraints表获取此信息,当我尝试使用ado.net数据读取器读取此信息时,尽管该表中的“定义”列具有值,但始终为空。

SQL脚本(DDL,用于获取CheckConstraints的存储过程,存储过程的执行状态)

GO

/****** Object:  Table [dbo].[Customer]    Script Date: 7/10/2019 3:24:22 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Customer](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [CompanyId] [smallint] NOT NULL,
    [Prefix] [varchar](4) NOT NULL,
    [FirstName] [varchar](50) NOT NULL,
    [LastName] [varchar](50) NOT NULL,
    [MiddleName] [varchar](50) NULL,
    [Suffix] [varchar](4) NULL,
    [NickName] [varchar](10) NULL,
    [ProfilePictureName] [varchar](50) NULL,
    [Company] [varchar](100) NULL,
    [DateOfBirth] [date] NOT NULL,
    [DateOfDeath] [date] NULL,
    [Gender] [char](1) NOT NULL,
    [Type] [varchar](10) NOT NULL,
    [IsActive] [char](1) NULL,
    [CreatedBy] [varchar](50) NOT NULL,
    [CreatedOn] [datetime2](7) NOT NULL,
    [UpdatedBy] [varchar](50) NULL,
    [UpdatedOn] [datetime2](7) NULL,
    [Process] [varchar](100) NULL,
    [MessageId] [varchar](50) NOT NULL,
    [SysStartDate] [datetime2](2) GENERATED ALWAYS AS ROW START NOT NULL,
    [SysEndDate] [datetime2](2) GENERATED ALWAYS AS ROW END NOT NULL,
 CONSTRAINT [PK_CUSTOMER] PRIMARY KEY CLUSTERED 
(
    [Id] ASC,
    [CompanyId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
    PERIOD FOR SYSTEM_TIME ([SysStartDate], [SysEndDate])
) ON [PRIMARY]
WITH
(
SYSTEM_VERSIONING = ON ( HISTORY_TABLE = [dbo].[MSSQL_TemporalHistoryFor_601769201] )
)
GO

ALTER TABLE [dbo].[Customer] ADD  DEFAULT ('Y') FOR [IsActive]
GO

ALTER TABLE [dbo].[Customer]  WITH CHECK ADD  CONSTRAINT [CUSTOMER_PREFIX_CHECK] CHECK  (([Prefix]='Dr' OR [Prefix]='Miss' OR [Prefix]='Ms' OR [Prefix]='Mrs' OR [Prefix]='Mr'))
GO

ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [CUSTOMER_PREFIX_CHECK]
GO

ALTER TABLE [dbo].[Customer]  WITH CHECK ADD  CONSTRAINT [CUSTOMER_SUFFIX_CHECK] CHECK  (([Suffix]='RN' OR [Suffix]='MD' OR [Suffix]='ESQ' OR [Suffix]='DO' OR [Suffix]='DDS' OR [Suffix]='DDM' OR [Suffix]='III' OR [Suffix]='II' OR [Suffix]='I' OR [Suffix]='Sr' OR [Suffix]='Jr'))
GO

ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [CUSTOMER_SUFFIX_CHECK]
GO

ALTER TABLE [dbo].[Customer]  WITH CHECK ADD  CONSTRAINT [CUSTOMER_TYPE_CHECK] CHECK  (([Type]='Customer' OR [Type]='VENDOR' OR [Type]='INSIDER' OR [Type]='ANALYST' OR [Type]='INVESTOR'))
GO

ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [CUSTOMER_TYPE_CHECK]
GO




CREATE PROCEDURE [dbo].[GetCheckConstraints_Dup](@tableName as varchar(200))
AS
BEGIN
select 
    col.[name] as column_name,
    con.[definition] As [constraint_value]
from sys.check_constraints con
    left outer join sys.objects t
        on con.parent_object_id = t.object_id
    left outer join sys.all_columns col
        on con.parent_column_id = col.column_id
        and con.parent_object_id = col.object_id
where t.[name]=@tableName and con.is_disabled=0
order by con.name;
End;

GO

exec GetCheckConstraints_Dup 'Customer'

SQL Server Result

C#

        public static List<Constraints> GetConstraints(string tableName,string connectionString)
        {
            var constraints = new List<Constraints>();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                //SqlDataReader
                connection.Open();
                SqlCommand cmd = new SqlCommand("DBO.GetCheckConstraints_Dup", connection);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add("@tableName", SqlDbType.VarChar).Value = tableName;

                using (SqlDataReader dataReader = cmd.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        constraints.Add(new Constraints() { FieldName = dataReader["column_name"].ToString(), Constraint = ConstraintType.Check, ConstraintValue = dataReader["constraint_value"].ToString() });

                    }
                }
            }

            return constraints;
        }

1 个答案:

答案 0 :(得分:0)

对我来说没有复制品。会复制吗?

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApp18
    {
        class Program
        {

            static string ddl = @"
    GO

    --if exists (select * from sys.tables where name = 'Customer')
   -- begin
    --    ALTER TABLE [dbo].[Customer] SET ( SYSTEM_VERSIONING = OFF)
    --    DROP TABLE [dbo].[Customer]
    --    DROP TABLE [dbo].[MSSQL_TemporalHistoryFor_601769201]
    --end

    go
    /****** Object:  Table [dbo].[Customer]    Script Date: 7/10/2019 3:24:22 PM ******/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TABLE [dbo].[Customer](
        [Id] [bigint] IDENTITY(1,1) NOT NULL,
        [CompanyId] [smallint] NOT NULL,
        [Prefix] [varchar](4) NOT NULL,
        [FirstName] [varchar](50) NOT NULL,
        [LastName] [varchar](50) NOT NULL,
        [MiddleName] [varchar](50) NULL,
        [Suffix] [varchar](4) NULL,
        [NickName] [varchar](10) NULL,
        [ProfilePictureName] [varchar](50) NULL,
        [Company] [varchar](100) NULL,
        [DateOfBirth] [date] NOT NULL,
        [DateOfDeath] [date] NULL,
        [Gender] [char](1) NOT NULL,
        [Type] [varchar](10) NOT NULL,
        [IsActive] [char](1) NULL,
        [CreatedBy] [varchar](50) NOT NULL,
        [CreatedOn] [datetime2](7) NOT NULL,
        [UpdatedBy] [varchar](50) NULL,
        [UpdatedOn] [datetime2](7) NULL,
        [Process] [varchar](100) NULL,
        [MessageId] [varchar](50) NOT NULL,
        [SysStartDate] [datetime2](2) GENERATED ALWAYS AS ROW START NOT NULL,
        [SysEndDate] [datetime2](2) GENERATED ALWAYS AS ROW END NOT NULL,
     CONSTRAINT [PK_CUSTOMER] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC,
        [CompanyId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
        PERIOD FOR SYSTEM_TIME ([SysStartDate], [SysEndDate])
    ) ON [PRIMARY]
    WITH
    (
    SYSTEM_VERSIONING = ON ( HISTORY_TABLE = [dbo].[MSSQL_TemporalHistoryFor_601769201] )
    )
    GO

    ALTER TABLE [dbo].[Customer] ADD  DEFAULT ('Y') FOR [IsActive]
    GO

    ALTER TABLE [dbo].[Customer]  WITH CHECK ADD  CONSTRAINT [CUSTOMER_PREFIX_CHECK] CHECK  (([Prefix]='Dr' OR [Prefix]='Miss' OR [Prefix]='Ms' OR [Prefix]='Mrs' OR [Prefix]='Mr'))
    GO

    ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [CUSTOMER_PREFIX_CHECK]
    GO

    ALTER TABLE [dbo].[Customer]  WITH CHECK ADD  CONSTRAINT [CUSTOMER_SUFFIX_CHECK] CHECK  (([Suffix]='RN' OR [Suffix]='MD' OR [Suffix]='ESQ' OR [Suffix]='DO' OR [Suffix]='DDS' OR [Suffix]='DDM' OR [Suffix]='III' OR [Suffix]='II' OR [Suffix]='I' OR [Suffix]='Sr' OR [Suffix]='Jr'))
    GO

    ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [CUSTOMER_SUFFIX_CHECK]
    GO

    ALTER TABLE [dbo].[Customer]  WITH CHECK ADD  CONSTRAINT [CUSTOMER_TYPE_CHECK] CHECK  (([Type]='Customer' OR [Type]='VENDOR' OR [Type]='INSIDER' OR [Type]='ANALYST' OR [Type]='INVESTOR'))
    GO

    ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [CUSTOMER_TYPE_CHECK]
    GO




    CREATE OR ALTER PROCEDURE [dbo].[GetCheckConstraints_Dup](@tableName as varchar(200))
    AS
    BEGIN
    select 
        col.[name] as column_name,
        con.[definition] As [constraint_value]
    from sys.check_constraints con
        left outer join sys.objects t
            on con.parent_object_id = t.object_id
        left outer join sys.all_columns col
            on con.parent_column_id = col.column_id
            and con.parent_object_id = col.object_id
    where t.[name]=@tableName and con.is_disabled=0
    order by con.name;
    End;

    GO
    ";
            static IEnumerable<string> GetBatches(string script)
            {
                var rdr = new System.IO.StringReader(script);
                var sb = new StringBuilder();
                while (true)
                {
                    var l = rdr.ReadLine()?.Trim();
                    if (l == null)
                    {
                        var batch = sb.ToString().Trim();
                        if (batch.Length > 0)
                            yield return sb.ToString();
                        break;
                    }
                    else if (l.Equals( "GO", StringComparison.OrdinalIgnoreCase))
                    {

                        var batch = sb.ToString().Trim();
                        if (batch.Length > 0)
                            yield return sb.ToString();
                        sb.Clear();
                    }
                    else
                    {
                        sb.AppendLine(l.Trim());
                    }
                }
            }
            static void Main(string[] args)
            {
                var constr = "Server=localhost;database=tempdb;integrated security=true";

                using (var con = new SqlConnection(constr))
                {
                    con.Open();
                    foreach (var batch in GetBatches(ddl))
                    {

                        var cmd = con.CreateCommand();
                        cmd.CommandText = batch;
                        cmd.ExecuteNonQuery();
                    }

                    var constraints = GetConstraints("Customer", constr);
                    foreach (var constraint in constraints)
                    {
                        Console.WriteLine($"{constraint.FieldName} {constraint.ConstraintValue}");
                    }
                }

                Console.WriteLine("Hit any key to exit");
                Console.ReadKey();
            }
            public static List<Constraints> GetConstraints(string tableName, string connectionString)
            {
                var constraints = new List<Constraints>();
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    //SqlDataReader
                    connection.Open();
                    SqlCommand cmd = new SqlCommand("DBO.GetCheckConstraints_Dup", connection);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("@tableName", SqlDbType.VarChar).Value = tableName;

                    using (SqlDataReader dataReader = cmd.ExecuteReader())
                    {
                        while (dataReader.Read())
                        {

                            constraints.Add(new Constraints() { FieldName = dataReader["column_name"].ToString(), Constraint = "Check", ConstraintValue = dataReader["constraint_value"].ToString() });

                        }
                    }
                }

                return constraints;
            }

            public class Constraints
            {
                public string FieldName { get; internal set; }
                public string Constraint { get; internal set; }
                public string ConstraintValue { get; internal set; }
            }
        }
    }