Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何查找指向不同表的孤立记录(需要参数化)?_Sql_Tsql_Recursion_With Statement - Fatal编程技术网

Sql 如何查找指向不同表的孤立记录(需要参数化)?

Sql 如何查找指向不同表的孤立记录(需要参数化)?,sql,tsql,recursion,with-statement,Sql,Tsql,Recursion,With Statement,表A与许多表B、C、D等有1-1关系。。。并由两列定义: ObjectTypenvarchar100//另一个表的名称 _Guiduniqueidentifier//另一个表中的记录ID 此外,所有表都包含一个IsDeletedbit列 问题是: 如何列出从A点到B、C、D中不存在的所有记录。。。还是已删除=1组的记录 以下操作无效,因为ObjectType必须是参数: SELECT ObjectType, _Guid FROM A where NOT EXISTS (

表A与许多表B、C、D等有1-1关系。。。并由两列定义:

ObjectTypenvarchar100//另一个表的名称 _Guiduniqueidentifier//另一个表中的记录ID 此外,所有表都包含一个IsDeletedbit列

问题是:

如何列出从A点到B、C、D中不存在的所有记录。。。还是已删除=1组的记录

以下操作无效,因为ObjectType必须是参数:

SELECT ObjectType, _Guid FROM A
where 
    NOT EXISTS (
        select * from ObjectType where oid = _Guid
    )
以下操作也不起作用:

SELECT ObjectType, _Guid FROM A
where 
    NOT EXISTS (
        exec('select * from '+ObjectType+' where oid =''' + _Guid + '''')
    )

我缺少什么?

查询必须具有静态已知的结构才能优化和执行。不能使用动态表名

连接所有可能的表

SELECT *
FROM A
LEFT JOIN B ON ...
LEFT JOIN C ON ...
LEFT JOIN D ON ...
WHERE
 (B.IsDeleted IS NULL AND C.IsDeleted IS NULL AND D.IsDeleted IS NULL)
 OR (B.IsDeleted = 1 OR C.IsDeleted = 1 OR D.IsDeleted = 1)

我想我没有得到完全正确的条件,因为我们还需要匹配ObjectType。我把它留给你修理。重要的想法是连接所有可能的表。

下面这个糟糕的SQL似乎可以工作:

DECLARE @A_tmpTable TABLE (
    idx smallint Primary Key IDENTITY(1,1)
    , ObjectType nvarchar(200)
    , _Guid nvarchar(100)
    , Oid nvarchar(100)
)
DECLARE @orphanedA_tmpTable TABLE (
    Oid nvarchar(100)
)
DECLARE @_objectType nvarchar(200)
DECLARE @_Guid nvarchar(100)
DECLARE @_oid nvarchar(100)
DECLARE @i int, @numrows int  
DECLARE @found bit

-- populate temp table
INSERT @A_tmpTable SELECT ObjectType, _Guid, Oid FROM A WHERE IsDeleted = 0
--SELECT * FROM @A_tmpTable

-- foreach the @A_tmpTable
SET @i = 1;
SET @numrows = (SELECT COUNT(*) FROM @A_tmpTable)
--SELECT @i, @numrows 
IF @numrows > 0
    WHILE (@i <= @numrows)
    BEGIN
        SET @ObjectType = (SELECT TOP 1 ObjectType FROM @A_tmpTable WHERE idx = @i);
        SET @_Guid = (SELECT TOP 1 _Guid FROM @A_tmpTable WHERE idx = @i);
        SET @_oid = (SELECT TOP 1 Oid FROM @A_tmpTable WHERE idx = @i);

        DECLARE @SQL nvarchar(max) = 'IF EXISTS (SELECT * FROM '+@ObjectType+' WHERE OID =''' + @_Guid + ''' AND IsDeleted = 0) 
                SET @found = 1;
            ELSE
                SET @found = 0;
            ';
        -- check if table record exists and save the result in the @found variable
        exec sp_executesql @SQL, N'@found bit out', @found out

        IF @found = 0
            INSERT INTO @orphanedA_tmpTable (Oid) VALUES (@_oid);


        SET @i = @i + 1
    END

SELECT * FROM A WHERE Oid IN (SELECT Oid FROM @orphanedA_tmpTable)