用于检查表是否存在的存储过程

时间:2019-06-23 11:31:59

标签: sql sql-server

我已经有一段时间没有编程了,我陷入了一个问题。我正在构建一个小型应用程序,您可以从中选择爱尔兰的32个县之一。

在我名为BlackCorsetDatabase的数据库中,我只想使用存储过程。

我想先尝试查看表是否已连接,然后再尝试首先写入数据库。

这是我到目前为止编写的代码:

CREATE PROCEDURE [dbo].[CheckTableCountyExists]
    (@TableExists BIT)
AS
    IF EXISTS (SELECT * 
               FROM BlackCorsetDatabase 
               WHERE TABLE_NAME = 'County')
    BEGIN
        PRINT 'Table Exists'
        @TableExists = 1
    END
    ELSE
    BEGIN
        Print 'Table does not exists' 
        @TableExists = 0
    END

    RETURN @@TableExists = TableExists
Go

我想要的是1或0的输出,以便可以在C#中检查结果

2 个答案:

答案 0 :(得分:1)

您可以检查表是否以多种方式存在-例如,使用元数据表或尝试访问它。

无论哪种情况,您都将要使用动态SQL。

此外,我强烈建议使用 OUTPUT 参数而不是 RETURN 从存储过程返回值。如果需要 RETURN ,则可能需要存储的函数。

我喜欢Sami传递您要查找的组件名称的方法。这是一个应该工作的版本:

CREATE PROCEDURE dbo.CheckTableCountyExists (
    @DatabaseName SysName,
    @SchemaName SysName,
    @TableName SysName,
    @TableExists BIT = 0 OUTPUT
) AS
BEGIN
    DECLARE @sql NVARCHAR(MAX);

    SET @sql = '
SELET @TableExists =
          (CASE WHEN EXISTS (SELECT 1
                             FROM @DatabaseName.INFORMATION_SCHEMA.TABLES t
                             WHERE t.TABLE_SCHEMA = @SchemaName AND
                                   t.TABLE_NAME = @TableName
                            )
                THEN 1 ELSE 0
           END)';

    SET @sql = REPLACE(@sql, '@DatabaseName', QUOTENAME(@DatabaseName));

    EXEC sp_executesql @sql,
                       N'@SchemaName sysname, @TableName sysname, @TableExists BIT',
                       @SchemaName=@SchemaName, @TableName=@TableName, @TableExists=@TableExists;
END;

然后您将其称为:

DECLARE @isExists BIT = 0;

EXEC dbo.CheckTableExists N'BlackCorsetDatabase', 
                          N'dbo', 
                          N'County', 
                          @isExists OUTPUT;

SELECT @isExists;

但是,如果数据库不存在,则上述操作将失败。您可以使用TRY / CATCH来解决此问题。通用方法是:

CREATE PROCEDURE dbo.CheckTableCountyExists (
    @DatabaseName SysName,
    @SchemaName SysName,
    @TableName SysName,
    @TableExists BIT = 0 OUTPUT
) AS
BEGIN
    DECLARE @sql NVARCHAR(MAX);

    SET @sql = '
SELET @TableExists =
          (CASE WHEN EXISTS (SELECT 1
                             FROM @DatabaseName.INFORMATION_SCHEMA.TABLES t
                             WHERE t.TABLE_SCHEMA = @SchemaName AND
                                   t.TABLE_NAME = @TableName
                            )
                THEN 1 ELSE 0
           END)';

    SET @sql = REPLACE(@sql, '@DatabaseName', QUOTENAME(@DatabaseName));
    BEGIN TRY
        EXEC sp_executesql @sql,
                       N'@SchemaName sysname, @TableName sysname, @TableExists BIT',

@SchemaName=@SchemaName, 
@TableName=@TableName, 
@TableExists=@TableExists;
     END TRY
     BEGIN CATCH
         -- on any error, assume table does not exist
         SET @TableExists = 0
     END CATCH;
END;

注意:您可能会更详细地说明该错误。但是,很难想象这种情况下代码可以工作,但是动态SQL 中出现错误,并且要返回“ 1”。

Here是db <>小提琴。

答案 1 :(得分:0)

不需要所有这些代码,也不必使用RETURN返回一个值,它用于检查SP是成功还是失败。

您的SP可能像

CREATE PROCEDURE [dbo].[CheckTableCountyExists]
(
  @DatabaseName SysName,
  @SchemaName SysName,
  @TableName SysName,
  @TableExists BIT = 0 OUTPUT
)
AS
  SELECT @TableExists = 1
  FROM INFORMATION_SCHEMA.TABLES
  WHERE TABLE_CATALOG = @DatabaseName
        AND
        TABLE_SCHEMA = @SchemaName
        AND
        TABLE_NAME = @TableName;
Go

然后您可以将其用作

DECLARE @MyVar BIT = 0;

EXEC [dbo].[CheckTableCountyExists] N'MyDatabaseName, 
                                    N'MySchemaName', 
                                    N'MyTableName', 
                                    @MyVar;

SELECT @MyVar;

中,您可以检查输出变量@TableExists是否返回0(不存在)或1(存在)。