Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.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
C# SQL按照PK FK关系从多个表中递归复制行_C#_Sql_Database_Recursion - Fatal编程技术网

C# SQL按照PK FK关系从多个表中递归复制行

C# SQL按照PK FK关系从多个表中递归复制行,c#,sql,database,recursion,C#,Sql,Database,Recursion,我的任务是创建一个存储过程来复制数据库中与给定ID关联的每一条数据。这些数据跨越几十个表。每个表可能有几十个匹配的行 例如: 表帐户 pk=AccountID 表AccountSettings FK=AccountID 表用户 PK=UserID FK=AccountID 表UserContent PK=UserContentID FK=UserID 我想创建一个与AccountID关联的所有内容的副本(它将遍历几乎每个表)。该副本将有一个新的AccountID和UserContentID,但将

我的任务是创建一个存储过程来复制数据库中与给定ID关联的每一条数据。这些数据跨越几十个表。每个表可能有几十个匹配的行

例如:

表帐户
pk=AccountID

表AccountSettings
FK=AccountID

表用户
PK=UserID
FK=AccountID

表UserContent
PK=UserContentID
FK=UserID

我想创建一个与AccountID关联的所有内容的副本(它将遍历几乎每个表)。该副本将有一个新的AccountID和UserContentID,但将有相同的UserID。新数据需要在其各自的表中。 :)有趣,对吗

以上只是一个示例,但我将针对50或60个表这样的对象执行此操作。 我已经研究过使用CTE,但对它们还是有点模糊。这可能是最好的方法。我的SQL技能是。。。。。。到目前为止,我已经用它工作了大约40个小时:)

如有任何建议或指示,请向我们咨询。此外,我并不反对通过C#这样做,如果这可能或更好的话


提前感谢您提供的任何信息帮助。

解决此问题的最简单方法是蛮力方法:编写一个非常长的过程,分别处理每个表。这很容易出错,并且很难维护。但它的优点是不依赖数据库或数据库元数据处于任何特别一致的状态

如果您想要基于元数据工作的东西,事情会更有趣。您面临三个挑战:

  • 您需要以编程方式标识所有相关表
  • 您需要为所有50或60生成insert语句
  • 您需要为那些距离Account表一步或两步以上的表捕获生成的ID,以便它们可以在更多复制的记录中作为外键使用
  • 我在过去研究过这个问题,虽然我不能给你一个无懈可击的算法,但我可以给你一个一般的启发。换句话说:这就是我的方法

  • 使用更高版本的MS Entity Framework(您说过可以使用C),构建Account表和所有相关表的模型
  • 好好回顾一下。如果您的数据库与许多数据库类似,那么无论出于何种原因,应用程序假定的某些关系都不会在数据库中设置实际的外键关系。无论如何都要在模型中创建它们
  • 用C#编写一个小的递归例程,它可以处理Account对象并遍历所有相关的表。选择几个帐户实例,让它将表名和密钥信息转储到一个文件中。检查其完整性和合理性
  • 一旦您对拥有一个好的模型和一个好的算法感到满意,就可以开始破解代码了。您需要编写一个更复杂的算法来读取帐户并递归地克隆引用它的所有记录。为了做到这一点,您可能需要反射,但这并不难:您需要的所有元数据都将在那里的某个地方
  • 测试你的代码。留出足够的时间进行调试
  • 在步骤3中,使用第一个算法比较结果的完整性和准确性 EF方法的优点:随着数据库的变化,模型也会发生变化,如果代码是基于元数据的,它应该能够适应


    缺点:如果您有这样的现象,例如字段“实际上”是相同的,但类型不同,或者复杂的三方关系没有正确建模,或者嵌入了需要解析的CSV列表,那么这将不起作用。只有当数据库状态良好且建模良好时,它才能工作。否则你需要诉诸暴力

    在您的示例中,1个帐户可以有0-n个用户,但1个用户只能有0-1个帐户=>第二个帐户不可能有相同的用户ID(当然,如果您不想删除用户与第一个帐户的连接),哇。我不会这样做的。CTE只会递归100次,因此您可能会超过此值。为什么不根据临时表中表的外键继续添加到临时表中,直到没有添加新行为止?@saarp:为什么CTE只会递归100次?这是一个荒谬的假设。您使用的是哪种数据库管理系统?PostgreSQL?神谕DB2?@一匹没有名字的马:不是假设,而是事实。请参阅上面的MAXRECURSION参数示例(默认值为100,介于0和32767之间)。谢谢。最后我把所有的事情都写了出来。它相当大,大约有1800行,但它工作得非常好。让它保持最新是一件痛苦的事。谢谢你对这件事的想法。我最终在我的解决方案中使用了EF,这比我最初预期的要容易得多,所以我肯定会推荐使用它。最重要的是,它更易于维护,甚至更易于扩展。@Tfrascaoli感谢您的赞誉!我很高兴我的建议很有帮助!