Sql server 两个表作为用户定义函数的参数

Sql server 两个表作为用户定义函数的参数,sql-server,function,compare,udf,Sql Server,Function,Compare,Udf,我试图在SQLServer中创建一个函数,用于比较两个表,检查它们是否相同。我这样做有两个例外 这两个表应该完全相同,具有相同的数据格式和列名,并且两个表中的所有值都相同。这将是一个手动检查,因此如果存在差异,抛出的错误不是问题。目的只是看看创建表的两种方法是否会导致相同的表 我对SQL中的函数非常陌生,所以我不知道如何解决这个问题。 我想将这两个表作为参数传递给函数,以获得如下结果: CREATE FUNCTION DIFFERING_ROWS (@TABLE1, @TABLE2) RETUR

我试图在SQLServer中创建一个函数,用于比较两个表,检查它们是否相同。我这样做有两个例外

这两个表应该完全相同,具有相同的数据格式和列名,并且两个表中的所有值都相同。这将是一个手动检查,因此如果存在差异,抛出的错误不是问题。目的只是看看创建表的两种方法是否会导致相同的表

我对SQL中的函数非常陌生,所以我不知道如何解决这个问题。 我想将这两个表作为参数传递给函数,以获得如下结果:

CREATE FUNCTION DIFFERING_ROWS
(@TABLE1, @TABLE2)
RETURNS TABLE

AS
RETURN (
    SELECT *, 'A_not_B' as [Difference] FROM @TABLE1
    except
    SELECT *, 'A_not_B' as [Difference] FROM @TABLE2
    union all
    SELECT *, 'B_not_A' as [Difference] FROM @TABLE2
    except
    SELECT *, 'B_not_A' as [Difference] FROM @TABLE1
    )
END
这是如何正确实施的?
有人能帮我吗?

在函数中不能这样做。可以将表名作为参数传递的唯一方法是使用动态SQL,函数中不允许使用动态SQL。您可以使用存储过程执行此操作。

您不能在函数中执行此操作。可以将表名作为参数传递的唯一方法是使用动态SQL,函数中不允许使用动态SQL。您可以使用存储过程执行此操作。

如果表具有相同的列名,则可以创建此存储过程:

CREATE PROCEDURE checkEqualTables
@table1 varchar(100),
@table2 varchar(100)
AS
BEGIN

DECLARE @xCount int;

(SELECT @xCount = COUNT(*) from (SELECT column_name FROM information_schema.COLUMNS WHERE table_name=@table1) base
         where column_name not in (SELECT column_name FROM information_schema.COLUMNS WHERE table_name=@table2))

IF(@xCount <= 0)    
    print 'Tables are equal!';
ELSE
    print 'Tables are not equal!'    

END

如果表具有相同的列名,则可以创建此存储过程进行计数:

CREATE PROCEDURE checkEqualTables
@table1 varchar(100),
@table2 varchar(100)
AS
BEGIN

DECLARE @xCount int;

(SELECT @xCount = COUNT(*) from (SELECT column_name FROM information_schema.COLUMNS WHERE table_name=@table1) base
         where column_name not in (SELECT column_name FROM information_schema.COLUMNS WHERE table_name=@table2))

IF(@xCount <= 0)    
    print 'Tables are equal!';
ELSE
    print 'Tables are not equal!'    

END

好的,我从答案和评论中获取信息,研究如何将其应用到程序中,这就是我构建的:

我想这正是我想要的:

CREATE PROCEDURE checkEqualTables
@table1 nvarchar(100),
@table2 nvarchar(100)
AS
BEGIN
    DECLARE @SQL nvarchar(max);

SET @SQL =  'SELECT * FROM '    + @TABLE1 +
            'except
            SELECT * FROM '     + @TABLE2 +
            'union all
            SELECT * FROM '     + @TABLE2 +
            'except
            SELECT * FROM '     + @TABLE1    
    EXECUTE sp_executesql @SQL

END

好的,我从答案和评论中获取信息,研究如何将其应用到程序中,这就是我构建的:

我想这正是我想要的:

CREATE PROCEDURE checkEqualTables
@table1 nvarchar(100),
@table2 nvarchar(100)
AS
BEGIN
    DECLARE @SQL nvarchar(max);

SET @SQL =  'SELECT * FROM '    + @TABLE1 +
            'except
            SELECT * FROM '     + @TABLE2 +
            'union all
            SELECT * FROM '     + @TABLE2 +
            'except
            SELECT * FROM '     + @TABLE1    
    EXECUTE sp_executesql @SQL

END

那么作为一个存储过程,它会是什么样子呢?不是使用返回,而是使用动态SQL简单地执行SELECT。那么作为一个存储过程,它会是什么样子呢?不是使用返回,而是使用动态SQL简单地执行SELECT。这很容易出错。如果这两个表没有完全相同的列和数据类型,它将失败。当然,这首先取决于从函数中获取这些参数并将其转换为动态sql。当然,除非您尝试使用表值参数,否则您可以在函数中这样做。但是你发布的代码没有数据类型,所以我们在这里进行猜测。哦,是的,我会在问题中澄清这一点。这些表应该完全相同,具有相同的数据格式和列名。这将是一个手动检查,因此如果存在差异,抛出的错误不是问题。但是您是否传递表或表值参数的名称?这两个表的数据类型是什么?好的。因此,请切换到一个过程,并将查询转换为动态sql。请确保用QUOTENAME包装表名。如果名称中有空格之类的内容,它会很有帮助,还可以极大地降低sql注入的风险。这很容易出错。如果这两个表没有完全相同的列和数据类型,它将失败。当然,这首先取决于从函数中获取这些参数并将其转换为动态sql。当然,除非您尝试使用表值参数,否则您可以在函数中这样做。但是你发布的代码没有数据类型,所以我们在这里进行猜测。哦,是的,我会在问题中澄清这一点。这些表应该完全相同,具有相同的数据格式和列名。这将是一个手动检查,因此如果存在差异,抛出的错误不是问题。但是您是否传递表或表值参数的名称?这两个表的数据类型是什么?好的。因此,请切换到一个过程,并将查询转换为动态sql。请确保用QUOTENAME包装表名。如果名称中有空格之类的内容,这会很有帮助,而且会极大地降低sql注入的风险。我很确定OP对内容感兴趣,而不是实际的列。我很确定OP对内容感兴趣,而不是实际的列。