我有下表:
CREATE TABLE X (
A SOMETYPE NOT NULL,
B SOMETYPE NOT NULL,
C SOMETYPE NULL,
PRIMARY KEY (A,B),
FOREIGN KEY (A,C) REFERENCES X (A,B)
);
存储在其中的实体X
是按层次结构组织的:如果(A1,B1,C1)
存在一行,C1 IS NOT NULL
则认为该行是(A1,C1,C2)
任何C2
内容的“子项” 。由于项目不能从其自身衍生而来,因此我想将存在循环层次序列的行为定为非法:
-- legal
INSERT INTO X (A1,B1,NULL);
INSERT INTO X (A1,B2,B1);
INSERT INTO X (A1,B3,B2);
INSERT INTO X (A1,B4,B2);
-- currently legal, but I want to make it illegal
UPDATE X SET C = B1 WHERE B = B1; /* B1-B1 */
UPDATE X SET C = B2 WHERE B = B1; /* B1-B2-B1 */
UPDATE X SET C = B3 WHERE B = B1; /* B1-B2-B3-B1 */
UPDATE X SET C = B4 WHERE B = B1; /* B1-B2-B4-B1 */
UPDATE X SET C = B2 WHERE B = B2; /* B2-B2 */
UPDATE X SET C = B3 WHERE B = B2; /* B2-B3-B2 */
UPDATE X SET C = B4 WHERE B = B2; /* B2-B4-B2 */
UPDATE X SET C = B3 WHERE B = B3; /* B3-B3 */
UPDATE X SET C = B4 WHERE B = B4; /* B4-B4 */
我该怎么做呢?
另外,我可以在表中添加一个表示层次结构中“级别”的字段:
CREATE TABLE X (
A SOMETYPE NOT NULL,
B SOMETYPE NOT NULL,
C SOMETYPE NULL,
LEVEL INT NOT NULL,
PRIMARY KEY (A,B),
FOREIGN KEY (A,C) REFERENCES X (A,B)
);
然后,我要求将其设置LEVEL
为0
when C IS NULL
,parent's LEVEL + 1
否则。
我正在使用SQL Server 2008 R2。
为了检查循环引用,我使用了触发器和递归CTE:
CREATE TRIGGER trgIU_X_CheckCircularReferences
ON dbo.X
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Results TABLE ([Exists] BIT);
WITH CteHierarchy
AS
(
SELECT x.A, x.B, X.C, 1 AS [Type]
FROM inserted i
JOIN X x ON i.A = x.A AND i.C = x.B
UNION ALL
SELECT x.A, x.B, X.C, 2 AS [Type]
FROM CteHierarchy i
JOIN X x ON i.A = x.A AND i.C = x.B
WHERE NOT EXISTS
(
SELECT *
FROM inserted a
WHERE a.A = x.A AND a.B = x.B
)
)
INSERT @Results ([Exists])
SELECT TOP(1) 1
FROM CteHierarchy h
JOIN X x ON h.A = x.A AND h.C = x.B
OPTION(MAXRECURSION 1000);
IF EXISTS(SELECT * FROM @Results)
BEGIN
ROLLBACK;
RAISERROR('Circular references detected', 16, 1);
END
END
GO
现在,我们可以运行一些测试:
--Test 1 - OK
PRINT '*****Test 1 - OK*****';
SELECT * FROM X;
BEGIN TRANSACTION;
UPDATE X
SET C = 'B1'
WHERE B = 'B4';
SELECT * FROM X;
--This transaction can be commited without problems
--but I will cancel all modification so we can run the second test
ROLLBACK TRANSACTION;
PRINT '*****End of test 1*****';
GO
--Test 2 - NOT OK
PRINT '*****Test 2 - NOT OK*****';
SELECT * FROM X;
BEGIN TRANSACTION;
UPDATE X
SET C = 'B1'
WHERE B = 'B1';
--Useless in this case (test 2 & test 3)
--Read section [If a ROLLBACK TRANSACTION is issued in a trigger] from http://msdn.microsoft.com/en-us/library/ms181299.aspx
SELECT * FROM X;
--Useless
ROLLBACK TRANSACTION;
--Useless
PRINT '*****End of test 2*****';
GO
PRINT '*****Test 3 - NOT OK*****';
SELECT * FROM X;
BEGIN TRANSACTION;
UPDATE X
SET C = 'B4'
WHERE B = 'B1';
GO
结果:
*****Test 1 - OK*****
(4 row(s) affected)
(0 row(s) affected)
(1 row(s) affected)
(4 row(s) affected)
*****End of test 1*****
*****Test 2 - NOT OK*****
(4 row(s) affected)
(1 row(s) affected)
Msg 50000, Level 16, State 1, Procedure trgIU_X_CheckCircularReferences, Line 34
Circular references detected
Msg 3609, Level 16, State 1, Line 8
The transaction ended in the trigger. The batch has been aborted.
*****Test 3 - NOT OK*****
(4 row(s) affected)
(1 row(s) affected)
Msg 50000, Level 16, State 1, Procedure trgIU_X_CheckCircularReferences, Line 34
Circular references detected
Msg 3609, Level 16, State 1, Line 7
The transaction ended in the trigger. The batch has been aborted.
对于第二个测试,您可以看到此触发器如何取消(ROLLBACK TRANSACTION
)事务,并且在UPDATE之后,什么都没有执行(在当前 批次中
)。
目前我正在用这个样本进行拓扑排序,并对https://www.geeksforgeeks.org/topological-sorting/做了一些修改 我用它来排序要求解的变量的顺序。 样本 每个变量都有一个唯一整数,并存储在一个映射中 创建图形并添加边时,总共有4个顶点,因此我的代码将像这样构造图形 排序并按相反顺序得到结果后,它是正确的c 一切都很好,但我需要检测图中的循环引用。假设变量是 有
问题内容: 我在excel中有父子数据,该数据已加载到运行MS SQL Server的第3方系统中。数据表示有向(希望)非循环图。第三方意味着我在架构中没有完全自由的手。excel数据是其他文件的串联,并且存在以下可能性:在各个文件之间的交叉引用中,有人引起了循环- 即X是Y的子级(X-> Y),然后是其他地方(Y-> A- > BX)。我可以在Excel或SQL Server数据库上编写vb,v
假定我在一个大的JavaScript对象中有一个循环引用 浏览器抛出 “TypeError:将循环结构转换为JSON” (这是意料之中的)
我有一个简单的类,如下所示: 但我收到以下错误消息: 检测到服务“App\Algorithm\Calculator”的循环引用,路径:“App\Algorithm\Calculator”- MatchService.php 问题是,但我到底做错了什么?
问题内容: 我想用JAXB将我的pojo转换为json,我的pojo具有一对多的关系,当我将pojo转换为json时,JAXB会产生错误“在对象图中检测到一个循环。这将导致无限深的XML”。 我从网上读到,可以通过@XmlID和@XmlIDREF的帮助解决此问题,但是有一个问题,我的Id属性不是String类型,而是Long。据我所知,@ XmlID只能与String属性一起使用。 其他网站建议使
问题内容: 我有2张表: 在部门中: numEmpl是主键 numDept是对Departamentos(numDept)的外键引用。在部门中: numDept是主键 numDirect是对Empleados(numEmpl)的外键引用 因此,有一个循环参考。 首先,我创建了表格: 现在,我在它们之间创建引用: 它起作用了,所以现在我尝试插入一些数据: 但是现在它引发了一个错误,告诉我不能在循环引