AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-6236

ErikE's questions

Martin Hope
ErikE
Asked: 2016-11-29 22:24:14 +0800 CST

使用 Netbackup 7.7 `WITH KEEP_CDC`

  • 3

我在生产数据库中使用SQL Server Change Data Capture 。令我惊讶的是,我发现将该数据库还原到较低环境时,CDC 数据没有保留——所有表、函数等都消失了,因为 SQL Server 在还原到任何其他环境的恢复阶段删除了 CDC 信息除了发起备份的数据库。

我了解到有一个RESTORE选项 ,KEEP_CDC它可以与RECOVERY选项(作为还原链的最后一步)结合使用,以防止 CDC 信息被删除。

Transact-SQL 参考:RESTORE 参数

保持CDC

支持者:恢复

当在另一台服务器上恢复数据库备份或日志备份并恢复数据库时,应使用 KEEP_CDC 来防止更改数据捕获设置被删除。不允许在使用 NORECOVERY 选项还原备份时指定此选项。

我们的组织使用 NetBackup 作为备份和还原数据库的主要方式。获得备份文件之外的备份文件并不是一件容易的事,而且可能永远不会成为例行公事。我们有一个网站,可以让开发人员将生产备份恢复到其他环境,而无需亲自接触文件。

问题:那么我真正需要的是什么——查明 NetBackup 7.7 中是否有一种方法可以指定额外的还原选项,以便WITH_CDC可以将其传递给 RESTORE 命令?还是 NetBackup 没有使用 trueRESTORE语句?似乎它必须以某种方式使用内置的 SQL Server 还原功能,否则它无法正确触发还原的恢复阶段。或者也许我只是超出了我的深度,在这里。

我找不到太多关于 NetBackup 能力的信息,一位高级数据库工程师向我保证,NetBackup 7.7 做不到这一点。然而,我想知道他搜索得有多深,以及是否有人可能更熟悉该产品可能知道破解这样的东西的方法。显然 8.0 版即将推出,但我似乎又不能在网上找到一个可靠的文档来源,了解如何实现这一点。(似乎“附加命令行参数”是可能的,即使该选项未通过命名开关或其他设置明确支持。)

sql-server sql-server-2012
  • 2 个回答
  • 212 Views
Martin Hope
ErikE
Asked: 2016-11-19 12:03:59 +0800 CST

依赖 INSERT 的 OUTPUT 子句的顺序是否安全?

  • 25

鉴于此表:

CREATE TABLE dbo.Target (
   TargetId int identity(1, 1) NOT NULL,
   Color varchar(20) NOT NULL,
   Action varchar(10) NOT NULL, -- of course this should be normalized
   Code int NOT NULL,
   CONSTRAINT PK_Target PRIMARY KEY CLUSTERED (TargetId)
);

在两个稍微不同的场景中,我想插入行并从标识列返回值。

方案 1

INSERT dbo.Target (Color, Action, Code)
OUTPUT inserted.TargetId
SELECT t.Color, t.Action, t.Code
FROM
   (VALUES
      ('Blue', 'New', 1234),
      ('Blue', 'Cancel', 4567),
      ('Red', 'New', 5678)
   ) t (Color, Action, Code)
;

方案 2

CREATE TABLE #Target (
   Color varchar(20) NOT NULL,
   Action varchar(10) NOT NULL,
   Code int NOT NULL,
   PRIMARY KEY CLUSTERED (Color, Action)
);

-- Bulk insert to the table the same three rows as above by any means

INSERT dbo.Target (Color, Action, Code)
OUTPUT inserted.TargetId
SELECT t.Color, t.Action, t.Code
FROM #Target
;

问题

我是否可以依赖从dbo.Target表插入返回的标识值按照它们在 1)VALUES子句和 2)#Target表中存在的顺序返回,以便我可以通过它们在输出行集中的位置将它们关联回原始输入?

以供参考

下面是一些精简的 C# 代码,演示了应用程序中发生的事情(场景 1,即将转换为使用SqlBulkCopy):

public IReadOnlyCollection<Target> InsertTargets(IEnumerable<Target> targets) {
   var targetList = targets.ToList();
   const string insertSql = @"
      INSERT dbo.Target (
         CoreItemId,
         TargetDateTimeUtc,
         TargetTypeId,
      )
      OUTPUT
         Inserted.TargetId
      SELECT
         input.CoreItemId,
         input.TargetDateTimeUtc,
         input.TargetTypeId,
      FROM
         (VALUES
            {0}
         ) input (
            CoreItemId,
            TargetDateTimeUtc,
            TargetTypeId
         );";
   var results = Connection.Query<DbTargetInsertResult>(
      string.Format(
         insertSql,
         string.Join(
            ", ",
            targetList
               .Select(target => $@"({target.CoreItemId
                  }, '{target.TargetDateTimeUtc:yyyy-MM-ddTHH:mm:ss.fff
                  }', {(byte) target.TargetType
                  })";
               )
         )
      )
      .ToList();
   return targetList
      .Zip( // The correlation that relies on the order of the two inputs being the same
         results,
         (inputTarget, insertResult) => new Target(
            insertResult.TargetId, // with the new TargetId to replace null.
            inputTarget.TargetDateTimeUtc,
            inputTarget.CoreItemId,
            inputTarget.TargetType
         )
      )
      .ToList()
      .AsReadOnly();
}
sql-server sql-server-2012
  • 1 个回答
  • 3902 Views
Martin Hope
ErikE
Asked: 2016-11-18 14:39:48 +0800 CST

<> 和 != 在 SQL Server 中的性能相同的权威来源

  • 89

考虑一下这个关于 SO 的答案,它可以让询问者对<>运营商感到放心:

<>是……和……一样!=。

但随后一位评论者插嘴说:

确实,它们在功能上是相同的。但是,SQL 优化器如何使用它们却大不相同。=/!= 被简单地评估为真/假,而 <> 意味着引擎必须查看该值是大于还是小于,这意味着更多的性能开销。只是在编写可能很昂贵的查询时要考虑的事情。

我相信这是错误的,但为了解决潜在的怀疑论者,我想知道是否有人可以提供权威或规范的来源来证明这些运算符不仅在功能上相同,而且在所有方面都相同?

sql-server performance
  • 4 个回答
  • 17469 Views
Martin Hope
ErikE
Asked: 2013-05-29 10:03:10 +0800 CST

sp_executesql 将语句添加到执行的动态脚本?

  • 4

问题:

据我所知,sp_executesql将语句添加到提交的动态 SQL 脚本的开头。但是,SQL Profiler 跟踪不会捕获额外的语句,DBCC OUTPUTBUFFER. 所以:

  1. 有什么方法可以查看添加到提交的动态 SQL 批处理中的额外语句sp_executesql?
  2. 任何人都可以明确确认我对额外陈述的结论是正确/不正确的吗?

背景

我有一个数据库,其中一些对象(视图、同义词、SP)是根据Script表中的数据重写的。如果将数据库移动到另一台服务器,则存储过程会循环遍历Script表的行,将提供的 SQL 脚本中的某些键值替换为为新服务器上下文定义的键值,然后运行该脚本。

一切正常,直到我通过相同的机制进行了一些调整以添加对脚本权限的支持。该数据库与供应商的产品集成,并且在每个环境中,供应商的数据库可以有不同的用户,为了报告目的,必须授予该用户访问我数据库中特定视图的权限。因此,我必须查询该用户(从供应商的数据库中),然后使用该名称在我的数据库中创建该用户(如果它不存在)并最终授予SELECT权限。这需要更冗长的脚本编写并在动态 sql 中执行动态 sql,因此我想传入外部脚本的@Debug参数,以便在尝试执行之前查看正在生成的额外脚本并确认其正确性。

除了更改可以编写脚本的对象类型并使DROP脚本可选之外,我为适应@Debug参数所做的唯一重大更改是更改此:

EXEC (@CreateSQL);

对此:

EXEC sp_executesql @CreateSQL, N'@Debug bit', @Debug;

然后我遇到了一个问题:Script无法再创建表中的一个存储过程,尽管DROP之前它仍然可以正常工作。我得到的结果是这样的:

消息 156,第 15 级,状态 1,第 1 行

关键字“PROCEDURE”附近的语法不正确。

这很混乱,但折腾了半天,终于搞清楚了问题:在执行前sp_executesql偷偷加一条语句,把参数绑定到动态SQL上。DECLARE由于CREATE PROCEDUREmust 是批处理中唯一的语句,但是现在该CREATE PROCEDURE行之前有一个额外的语句,因此会引发错误。它确实说Line 1——这进一步误导了我——但这显然是由引擎调整的,所以人们在处理错误时不会对自己脚本的行号感到困惑。

该问题的解决方案是检测正在使用哪种类型的对象并且不传递@Debug参数,因此必须没有其他语句的脚本可以正常工作。一个快速的改变完成了这项工作:

IF @ScriptType IN ('Procedure', 'View', 'Function') BEGIN
   EXEC sp_executesql @CreateSQL;
END
ELSE BEGIN
   EXEC sp_executesql @CreateSQL, N'@Debug bit', @Debug;
END;

我也可以将我的动态 SQL 嵌套更深一层,以在动态 sql 中创建过程(同样,在表中的脚本中),但在我的情况下,这是一个不太理想的解决方案。

我怀疑使用OUTPUT变量 withsp_executesql还会在脚本末尾添加一个或多个语句,以使引擎能够捕获它们,很可能是在一个SELECT被默默吞下的语句中。

sql-server dynamic-sql
  • 2 个回答
  • 3256 Views
Martin Hope
ErikE
Asked: 2012-08-17 16:32:19 +0800 CST

为什么“查找”在 SQL Server 中作为函数保留字着色?

  • 14

在 SSMS 2208 中,标识符“Lookup”是粉红色的,就好像它是一个函数一样(与“Power”或“Convert”颜色相同)。为什么?

我在保留字的官方列表中找不到它。网络上的搜索似乎毫无用处,因为那里有很多与我的问题无关的“查找”术语。

sql-server-2008 ssms
  • 1 个回答
  • 1875 Views
Martin Hope
ErikE
Asked: 2012-07-05 14:09:38 +0800 CST

SQL Server 中多个工作人员的 FIFO 队列表

  • 18

我试图回答以下 stackoverflow 问题:

  • 我应该使用哪种 SQL Server 2005/2008 锁定方法来处理多个服务器应用程序实例中的单个表行?

在发布了一个有点幼稚的答案后,我想我会把钱放在嘴边,并实际测试我建议的场景,以确保我不会让 OP 去追逐野鹅。好吧,事实证明它比我想象的要困难得多(我敢肯定,这对任何人来说都不足为奇)。

以下是我尝试和思考的内容:

  • 首先,我在派生表中尝试了带有 ORDER BY 的 TOP 1 UPDATE,使用ROWLOCK, READPAST. 这会产生死锁并且还会乱序处理项目。它必须尽可能接近 FIFO,除非出现需要多次尝试处理同一行的错误。

  • 然后,我尝试使用、 、 和的各种组合将所需的下一个 QueueID 选择到一个变量中READPAST,并专门保留该行以供该会话更新。我尝试的所有变体都遇到了与以前相同的问题,并且对于某些与 的组合,抱怨:UPDLOCKHOLDLOCKROWLOCKREADPAST

    您只能在 READ COMMITTED 或 REPEATABLE READ 隔离级别中指定 READPAST 锁。

    这很令人困惑,因为它是READ COMMITTED 的。我以前遇到过这种情况,这很令人沮丧。

  • 自从我开始写这个问题以来,Remus Rusani 就发布了一个新的答案。我阅读了他的链接文章,发现他正在使用破坏性读取,因为他在回答中说“在网络调用期间保持锁定实际上是不可能的”。在阅读了他关于热点和需要锁定以进行任何更新或删除的页面的文章后,我担心即使我能够找出正确的锁来完成我正在寻找的事情,它也无法扩展并且可能无法处理大量并发。

现在我不知道该去哪里。在处理行的同时保持锁是真的无法实现(即使它不支持高 tps 或海量并发)?我错过了什么?

希望比我聪明的人和比我更有经验的人能提供帮助,下面是我正在使用的测试脚本。它已切换回 TOP 1 UPDATE 方法,但我将另一种方法留在了注释中,以防您也想探索它。

将这些中的每一个粘贴到一个单独的会话中,运行会话 1,然后快速运行所有其他会话。大约 50 秒后,测试将结束。查看来自每个会话的消息以了解它做了什么工作(或它是如何失败的)。第一个会话将显示一个行集,其中每秒拍摄一次快照,详细说明存在的锁和正在处理的队列项。它有时会起作用,而其他时候则根本不起作用。

第 1 节

/* Session 1: Setup and control - Run this session first, then immediately run all other sessions */
IF Object_ID('dbo.Queue', 'U') IS NULL
   CREATE TABLE dbo.Queue (
      QueueID int identity(1,1) NOT NULL,
      StatusID int NOT NULL,
      QueuedDate datetime CONSTRAINT DF_Queue_QueuedDate DEFAULT (GetDate()),
      CONSTRAINT PK_Queue PRIMARY KEY CLUSTERED (QueuedDate, QueueID)
   );

IF Object_ID('dbo.QueueHistory', 'U') IS NULL
   CREATE TABLE dbo.QueueHistory (
      HistoryDate datetime NOT NULL,
      QueueID int NOT NULL
   );

IF Object_ID('dbo.LockHistory', 'U') IS NULL
   CREATE TABLE dbo.LockHistory (
      HistoryDate datetime NOT NULL,
      ResourceType varchar(100),
      RequestMode varchar(100),
      RequestStatus varchar(100),
      ResourceDescription varchar(200),
      ResourceAssociatedEntityID varchar(200)
   );

IF Object_ID('dbo.StartTime', 'U') IS NULL
   CREATE TABLE dbo.StartTime (
      StartTime datetime NOT NULL
   );

SET NOCOUNT ON;

IF (SELECT Count(*) FROM dbo.Queue) < 10000 BEGIN
   TRUNCATE TABLE dbo.Queue;

   WITH A (N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
   B (N) AS (SELECT 1 FROM A Z, A I, A P),
   C (N) AS (SELECT Row_Number() OVER (ORDER BY (SELECT 1)) FROM B O, B W)
   INSERT dbo.Queue (StatusID, QueuedDate)
   SELECT 1, DateAdd(millisecond, C.N * 3, GetDate() - '00:05:00')
   FROM C
   WHERE C.N <= 10000;
END;

TRUNCATE TABLE dbo.StartTime;
INSERT dbo.StartTime SELECT GetDate() + '00:00:15'; -- or however long it takes you to go run the other sessions
GO
TRUNCATE TABLE dbo.QueueHistory;
SET NOCOUNT ON;

DECLARE
   @Time varchar(8),
   @Now datetime;
SELECT @Time = Convert(varchar(8), StartTime, 114)
FROM dbo.StartTime;
WAITFOR TIME @Time;

DECLARE @i int,
@QueueID int;
SET @i = 1;
WHILE @i <= 33 BEGIN
   SET @Now  = GetDate();
   INSERT dbo.QueueHistory
   SELECT
      @Now,
      QueueID
   FROM
      dbo.Queue Q WITH (NOLOCK)
   WHERE
      Q.StatusID <> 1;

   INSERT dbo.LockHistory
   SELECT
      @Now,
      L.resource_type,
      L.request_mode,
      L.request_status,
      L.resource_description,
      L.resource_associated_entity_id
   FROM
      sys.dm_tran_current_transaction T
      INNER JOIN sys.dm_tran_locks L
         ON L.request_owner_id = T.transaction_id;
   WAITFOR DELAY '00:00:01';
   SET @i = @i + 1;
END;

WITH Cols AS (
   SELECT *, Row_Number() OVER (PARTITION BY HistoryDate ORDER BY QueueID) Col
   FROM dbo.QueueHistory
), P AS (
   SELECT *
   FROM
      Cols
      PIVOT (Max(QueueID) FOR Col IN ([1], [2], [3], [4], [5], [6], [7], [8])) P
)
SELECT L.*, P.[1], P.[2], P.[3], P.[4], P.[5], P.[6], P.[7], P.[8]
FROM
   dbo.LockHistory L
   FULL JOIN P
      ON L.HistoryDate = P.HistoryDate

/* Clean up afterward
DROP TABLE dbo.StartTime;
DROP TABLE dbo.LockHistory;
DROP TABLE dbo.QueueHistory;
DROP TABLE dbo.Queue;
*/

第 2 节

/* Session 2: Simulate an application instance holding a row locked for a long period, and eventually abandoning it. */
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET NOCOUNT ON;
SET XACT_ABORT ON;

DECLARE
   @QueueID int,
   @Time varchar(8);
SELECT @Time = Convert(varchar(8), StartTime + '0:00:01', 114)
FROM dbo.StartTime;
WAITFOR TIME @Time;
BEGIN TRAN;

--SET @QueueID = (
--   SELECT TOP 1 QueueID
--   FROM dbo.Queue WITH (READPAST, UPDLOCK)
--   WHERE StatusID = 1 -- ready
--   ORDER BY QueuedDate, QueueID
--);

--UPDATE dbo.Queue
--SET StatusID = 2 -- in process
----OUTPUT Inserted.*
--WHERE QueueID = @QueueID;

SET @QueueID = NULL;
UPDATE Q
SET Q.StatusID = 1, @QueueID = Q.QueueID
FROM (
   SELECT TOP 1 *
   FROM dbo.Queue WITH (ROWLOCK, READPAST)
   WHERE StatusID = 1
   ORDER BY QueuedDate, QueueID
) Q

PRINT @QueueID;

WAITFOR DELAY '00:00:20'; -- Release it partway through the test

ROLLBACK TRAN; -- Simulate client disconnecting

第三节

/* Session 3: Run a near-continuous series of "failed" queue processing. */
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET XACT_ABORT ON;
SET NOCOUNT ON;
DECLARE
   @QueueID int,
   @EndDate datetime,
   @NextDate datetime,
   @Time varchar(8);

SELECT
   @EndDate = StartTime + '0:00:33',
   @Time = Convert(varchar(8), StartTime, 114)
FROM dbo.StartTime;

WAITFOR TIME @Time;

WHILE GetDate() < @EndDate BEGIN
   BEGIN TRAN;

   --SET @QueueID = (
   --   SELECT TOP 1 QueueID
   --   FROM dbo.Queue WITH (READPAST, UPDLOCK)
   --   WHERE StatusID = 1 -- ready
   --   ORDER BY QueuedDate, QueueID
   --);

   --UPDATE dbo.Queue
   --SET StatusID = 2 -- in process
   ----OUTPUT Inserted.*
   --WHERE QueueID = @QueueID;

   SET @QueueID = NULL;
   UPDATE Q
   SET Q.StatusID = 1, @QueueID = Q.QueueID
   FROM (
      SELECT TOP 1 *
      FROM dbo.Queue WITH (ROWLOCK, READPAST)
      WHERE StatusID = 1
      ORDER BY QueuedDate, QueueID
   ) Q

   PRINT @QueueID;

   SET @NextDate = GetDate() + '00:00:00.015';
   WHILE GetDate() < @NextDate SET NOCOUNT ON;
   ROLLBACK TRAN;
END

会话 4 及以上 - 任意数量

/* Session 4: "Process" the queue normally, one every second for 30 seconds. */
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET XACT_ABORT ON;
SET NOCOUNT ON;

DECLARE @Time varchar(8);
SELECT @Time = Convert(varchar(8), StartTime, 114)
FROM dbo.StartTime;
WAITFOR TIME @Time;

DECLARE @i int,
@QueueID int;
SET @i = 1;
WHILE @i <= 30 BEGIN
   BEGIN TRAN;

   --SET @QueueID = (
   --   SELECT TOP 1 QueueID
   --   FROM dbo.Queue WITH (READPAST, UPDLOCK)
   --   WHERE StatusID = 1 -- ready
   --   ORDER BY QueuedDate, QueueID
   --);

   --UPDATE dbo.Queue
   --SET StatusID = 2 -- in process
   --WHERE QueueID = @QueueID;

   SET @QueueID = NULL;
   UPDATE Q
   SET Q.StatusID = 1, @QueueID = Q.QueueID
   FROM (
      SELECT TOP 1 *
      FROM dbo.Queue WITH (ROWLOCK, READPAST)
      WHERE StatusID = 1
      ORDER BY QueuedDate, QueueID
   ) Q

   PRINT @QueueID;
   WAITFOR DELAY '00:00:01'
   SET @i = @i + 1;
   DELETE dbo.Queue
   WHERE QueueID = @QueueID;   
   COMMIT TRAN;
END
sql-server locking
  • 2 个回答
  • 20980 Views
Martin Hope
ErikE
Asked: 2012-02-14 10:43:22 +0800 CST

了解 SQL Server 锁定和并发的资源?

  • 9

正如最近的一个矿井锁定和并发问题所证明的那样是困难的。

您能否为中级到高级 SQL 专业人员推荐任何好的资源来对这些进行深入研究,如果学习得当,可以更好地导航该领域的所有固有陷阱?

我正在考虑各种资源——教程、博客、手册页、PASS 课程或任何资源。

sql-server locking
  • 4 个回答
  • 758 Views
Martin Hope
ErikE
Asked: 2012-02-12 17:06:23 +0800 CST

使用 SELECT-UPDATE 模式时管理并发

  • 26

假设您有以下代码(请忽略它很糟糕):

BEGIN TRAN;
DECLARE @id int
SELECT @id = id + 1 FROM TableA;
UPDATE TableA SET id = @id; --TableA must have only one row, apparently!
COMMIT TRAN;
-- @id is returned to the client or used somewhere else

在我看来,这不是正确管理并发。仅仅因为您有一个事务并不意味着其他人不会读取与您在获取更新语句之前所做的相同的值。

现在,让代码保持原样(我意识到这最好作为单个语句处理,甚至更好地使用自动增量/标识列)有什么方法可以使它正确处理并发并防止允许两个客户端获得相同的竞争条件身份证价值?

我很确定WITH (UPDLOCK, HOLDLOCK)在 SELECT 中添加 a 就可以了。SERIALIZABLE事务隔离级别似乎也可以工作,因为它拒绝任何其他人阅读您所做的事情,直到 tran 结束(更新:这是错误的。请参阅 Martin 的回答)。真的吗?他们会同样工作吗?一个比另一个更受欢迎吗?

想象一下做一些比 ID 更新更合法的事情——一些基于你需要更新的读取的计算。可能涉及许多表,其中一些您会写入,而另一些则不会。这里的最佳做法是什么?

写完这个问题后,我认为锁定提示更好,因为那样你只锁定你需要的表,但我很感激任何人的意见。

PS 不,我不知道最好的答案,真的很想得到更好的理解!:)

sql-server locking
  • 3 个回答
  • 14956 Views
Martin Hope
ErikE
Asked: 2012-02-10 11:51:19 +0800 CST

轻松显示两个表或查询之间不同的行

  • 20

想象一下,您有两个不同的表/查询,它们应该具有/返回相同的数据。你想验证这一点。什么是显示每个表中任何不匹配行的简单方法,就像下面的示例一样,比较每一列?假设表中有 30 列,其中许多列可以为 NULL。

当没有 PK 或每个 PK 可能有重复项时,仅加入 PK 列是不够的,并且必须使用 30 个正确处理 NULL 的连接条件以及令人讨厌的 WHERE 条件进行 FULL JOIN 将是一场灾难排除匹配的行。

通常,当我针对未清理或未完全理解的数据编写新查询时,问题最严重,并且 PK 在逻辑上可用的可能性极低。我设计了两种不同的方法来解决问题,然后比较它们的结果,这些差异突出了我不知道的数据中的特殊情况。

结果需要如下所示:

Which   Col1   Col2   Col3   ... Col30
------  ------ ------ ------     ------
TableA  Cat    27     86               -- mismatch
TableB  Cat    27     105              -- mismatch
TableB  Cat    27     87               -- mismatch 2
TableA  Cat    128    92               -- no corresponding row
TableB  Lizard 83     NULL             -- no corresponding row

如果[Col1, Col2]确实是一个复合键,并且我们在最终结果中按它们排序,那么我们可以很容易地看到 A 和 B 有一行不同但应该是相同的,并且每一行都有另一行不存在。

在上面的示例中,不希望看到第一行两次。

这是用于设置示例表和数据的 DDL 和 DML:

CREATE TABLE dbo.TableA (
   Col1 varchar(10),
   Col2 int,
   Col3 int,
   Col4 varchar(10),
   Col5 varchar(10),
   Col6 varchar(10),
   Col7 varchar(10),
   Col8 varchar(10),
   Col9 varchar(10),
   Col10 varchar(10),
   Col11 varchar(10),
   Col12 varchar(10),
   Col13 varchar(10),
   Col14 varchar(10),
   Col15 varchar(10),
   Col16 varchar(10),
   Col17 varchar(10),
   Col18 varchar(10),
   Col19 varchar(10),
   Col20 varchar(10),
   Col21 varchar(10),
   Col22 varchar(10),
   Col23 varchar(10),
   Col24 varchar(10),
   Col25 varchar(10),
   Col26 varchar(10),
   Col27 varchar(10),
   Col28 varchar(10),
   Col29 varchar(10),
   Col30 varchar(10)
);

CREATE TABLE dbo.TableB (
   Col1 varchar(10),
   Col2 int,
   Col3 int,
   Col4 varchar(10),
   Col5 varchar(10),
   Col6 varchar(10),
   Col7 varchar(10),
   Col8 varchar(10),
   Col9 varchar(10),
   Col10 varchar(10),
   Col11 varchar(10),
   Col12 varchar(10),
   Col13 varchar(10),
   Col14 varchar(10),
   Col15 varchar(10),
   Col16 varchar(10),
   Col17 varchar(10),
   Col18 varchar(10),
   Col19 varchar(10),
   Col20 varchar(10),
   Col21 varchar(10),
   Col22 varchar(10),
   Col23 varchar(10),
   Col24 varchar(10),
   Col25 varchar(10),
   Col26 varchar(10),
   Col27 varchar(10),
   Col28 varchar(10),
   Col29 varchar(10),
   Col30 varchar(10)
);

INSERT dbo.TableA (Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9, Col10, Col11, Col12, Col13, Col14, Col15, Col16, Col17, Col18, Col19, Col20, Col21, Col22, Col23, Col24, Col25, Col26, Col27, Col28, Col29, Col30)
VALUES
   ('Cat', 27, 86, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Cat', 128, 92, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Porcupine', NULL, 42, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Tapir', NULL, NULL, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0')
;

INSERT dbo.TableB (Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9, Col10, Col11, Col12, Col13, Col14, Col15, Col16, Col17, Col18, Col19, Col20, Col21, Col22, Col23, Col24, Col25, Col26, Col27, Col28, Col29, Col30)
VALUES
   ('Cat', 27, 105, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Cat', 27, 87, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Lizard', 83, NULL, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Porcupine', NULL, 42, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'),
   ('Tapir', NULL, NULL, 'a', 'b', 'c', 'd', 'e', 'f', 'g',' h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0');
sql-server sql-server-2008
  • 4 个回答
  • 112502 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve