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-140226

Elaskanator's questions

Martin Hope
Elaskanator
Asked: 2019-11-06 08:19:06 +0800 CST

在缺少 FETCH NEXT 的情况下防止无限循环

  • 1

发现这个代码错误导致了生产中的死循环:

DECLARE @BatchID INT
DECLARE MyCursor CURSOR FOR
    SELECT BatchID = ...
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @BatchID
WHILE @@FETCH_STATUS = 0
BEGIN
    ...
    IF [condition]
    BEGIN
        ...
        FETCH NEXT FROM MyCursor INTO @BatchID
    END
END
CLOSE MyCursor
DEALLOCATE MyCursor

假设需要一个游标是有保证的,有没有办法防止这个错误(除了更多的测试/代码审查)?

在其他语言中,我们FOREACH有为我们管理迭代进程的循环,或者FOR是事后诸葛亮的循环,那么 SQL Server 中是否有任何等价物可以防止诸如放错位置(或忘记!)之类的草率错误?

我从未见过 SQL 中的自定义循环需要对光标做任何花哨WHILE的事情,并且循环具有相同的风险(以及@BatchID 为DELETE #WorkData WHERE ID = @BatchID时的情况),那么对于典型的用例,如何以编程方式/干净地减轻这种风险?NULL


像这样的方法非常不吸引人:

DECLARE @BatchID INT
DECLARE MyCursor CURSOR FOR
    SELECT BatchID = -1--dummy entry to always be skipped
    UNION ALL SELECT BatchID = ...
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @BatchID
WHILE @@FETCH_STATUS = 0
BEGIN
    FETCH NEXT FROM MyCursor INTO @BatchID
    IF @@FETCH_STATUS = 0
    BEGIN
        ...
    END
END
CLOSE MyCursor
DEALLOCATE MyCursor

在我看来,@@FETCH_STATUS在中间没有任何游标位置/控制语句的情况下连续检查两次可能是 SQL Server猜测是否存在此类错误的有效方法,因为我使用游标的经验从未见过连续两次检查故意(至少没有嵌套游标,但那些仍然有控制语句,例如OPEN和CLOSE检查@@FETCH_STATUS外部游标之间)。

PS[condition]这一次相当于“不是DST过渡日”(这是这个星期天)。更多时区错误!

我对语言特性最感兴趣,以实现与其他语言如何处理 for 循环的事后考虑子句(例如i++in for (int i = 0; i < myArray.Length; i++))相同的自动提供的保证。个人负责的事情越少,出错的地方就越少,审计我们系统中成千上万的存储过程将是一项艰巨的任务,特别是因为其中许多不恰当地迭代数据而不是使用已经基于集合的逻辑。

sql-server cursors
  • 1 个回答
  • 325 Views
Martin Hope
Elaskanator
Asked: 2019-07-19 10:27:23 +0800 CST

SSDT Publish 因错误而失败,甚至没有运行任何语句

  • 1

我的发布尝试因此错误而失败

消息 205,级别 16,状态 1,第 7572 行 所有使用 UNION、INTERSECT 或 EXCEPT 运算符组合的查询必须在其目标列表中具有相同数量的表达式。

采用老式建议在部署脚本执行之间打印状态消息,我将其范围缩小到:

在此处输入图像描述

由于 SQL Server 怪癖,行号不匹配,这就是为什么你必须PRINT像异教徒一样的东西(参见上面的链接)

请注意实际上没有执行任何语句。我还运行了一个详细的跟踪,确认没有执行任何操作:

在此处输入图像描述

两个语句之间的控制流语句怎么PRINT可能导致错误?!

sql-server sql-server-2014
  • 1 个回答
  • 67 Views
Martin Hope
Elaskanator
Asked: 2019-07-04 11:51:30 +0800 CST

SQL Server - TRY/CATCH 在某些情况下不起作用

  • 6

如何编写在每个预期 * 情况下调用CATCH代码块的受保护的代码(而不像将所有内容包装在动态 SQL 中那样做一些时髦的垃圾)?

例如,这不起作用:

  1. 定义没有步骤的 SQL 代理作业
  2. 尝试在一个内部开始工作TRY/CATCH

    BEGIN TRY
        EXEC msdb.dbo.sp_start_job @job_name = 'my_empty_job'
    END TRY
    BEGIN CATCH
        SELECT [MyError] = 'Error caught: ' + ISNULL(ERROR_MESSAGE(), 'NULL')
    END CATCH
    

消息 22022,级别 16,状态 1,第 0 行 SQLServerAgent 错误:运行作业 my_empty_job(来自用户 xyz)的请求被拒绝,因为该作业没有作业步骤。

请注意,它的错误严重性为 16,因此它不应该绕过 CATCH 块。wtf?!?

CATCH如果作业正忙于处理请求(我在测试中发送垃圾邮件停止和启动请求),它也会绕过我的阻止。

消息 22022,级别 16,状态 1,第 0 行 SQLServerAgent 错误:运行作业 my_simple_job(来自用户 xyz)的请求被拒绝,因为作业已经有来自用户 xyz 的挂起请求。

相关案例:无效的链接服务器引用

PS请不要假设我只想要一个处理作业调用的窄范围解决方案。我正在寻找一个可以在未来重用的通用解决方案。

PPS 我能够捕捉到尝试启动/停止不存在的作业的情况(“指定的@job_name('missing_job')不存在。”)。为什么会有不同的行为?

* TRY/CATCH 无法处理的内容(tl;dr 错误严重性超出范围(10, 20))

sql-server sql-server-2014
  • 1 个回答
  • 1568 Views
Martin Hope
Elaskanator
Asked: 2018-08-07 11:58:49 +0800 CST

如何找到SSDT发布失败的错误代码?

  • 0

每次发布失败时,假设它通过了预览生成,错误行和执行的脚本示例对于帮助我跟踪错误源完全没有用,因为行号是相对于最后一条GO语句的,而执行的脚本没有' 总是出现在发布脚本中。

在这种情况下,它失败并出现以下错误:

非常普遍的错误

发布脚本中不存在执行的脚本:

它说它运行了这段代码

这是它在双击错误消息后在发布脚本中导航的位置:

根据发布的明显错误行

通常我都能根据报错信息查到,但这次我一头雾水,因为我能想到的相关关键词太普通了,看起来没救了。

看起来日志记录是 hackish,错误有时会出现在部署后脚本之前(例如,表触发器在不完整的数据上执行,因为发布设置只包含禁用 DDL 触发器的选项)。

我试过在发布期间运行 SQL Server Profiler,但该工具忽略了更重要的调试信息(并且被我的大型数据库项目淹没了)。也许升级以获得 Extended Events Profiler 的另一个原因?

SQL Server Profiler 跟踪结果无用

(我证实这个说法不是罪魁祸首)

sql-server sql-server-2014
  • 1 个回答
  • 326 Views
Martin Hope
Elaskanator
Asked: 2018-07-19 06:51:53 +0800 CST

SQL Server 切换为独占使用页面文件而不是 RAM 并有效地冻结了世界

  • 1

昨天我在我的 SQL Server 实例上运行了大约 3 个小时,运行了一个密集的计算,消耗了所有分配的物理 RAM (由于我的工作站硬件有限,我将它限制为 2GB),突然它(以及许多其他东西?)释放了所有他们的内存明显切换到专门使用页面文件。

在我被迫重新启动之后,我的计算机非常滞后(仅访问电源选项就花了 10 分钟)。

我能够在重新启动之前获得任务管理器的屏幕截图(我在后台以低更新速度运行)。调整窗口大小以显示最大历史记录后,它看起来像这样:

在此处输入图像描述

这种令人惊讶的行为导致停机。这是记录在案的功能吗?

我正在使用 Enterprise 2014 数据库引擎运行 Windows Server 2008 R2。

谢谢。

sql-server memory
  • 2 个回答
  • 2115 Views
Martin Hope
Elaskanator
Asked: 2018-06-28 07:42:08 +0800 CST

SQL Server - 有什么方法可以验证不匹配列名的插入语句?

  • 2

我喜欢在我的编码中冗长,所以我的典型插入语句如下所示:

INSERT INTO MyTable
(
     Column1
    ,Column2
    ,Column3
    ,Column4
    ,Column5
    ,Column6
)
SELECT
     Column1 = 'some value'
    ,Column2 = 'some value'
    ,Column4 = 'some value'
    ,Column3 = 'some value'
    ,Column5 = 'some value'
    ,Column6 = 'some value'
....

如果你没有注意到这句话的问题,那么你就和我一样被愚弄了无数次。

而这类缺陷真正阴险的部分是,它可能会在导致任何问题之前工作很长时间,当它失败时,即使有错误,它也不会指示真正的错误。

例如,如果第 3 列和第 4 列分别是数字和字符串类型,那么只有某些值会导致第 4 列出现运行时错误(而第 3 列不会出现运行时错误)类型转换失败(例如,'0' 转换为数字就好了但 'asdf' 不会)。

(在我的例子中,它被隐藏在受保护代码部分之外的 Service Broker 激活过程中(这是一个日志语句),所以我什至没有看到那个错误,而是得到了伪装成禁用我的队列的毒消息的孤立事务错误。)

有什么方法可以验证这种不需要人工校对的说法吗?

PS 我知道你可以给任何你喜欢的别名,但是在一个完全可选的上下文中,比如一个语句,使用某种自动化工具(即 IntelliSense)来指出可能的意外代码INSERT将是非常有用的。

更新:我已经向微软开放了这个反馈项目,因为这个明显缺乏的功能。

sql-server error-handling
  • 4 个回答
  • 905 Views
Martin Hope
Elaskanator
Asked: 2018-06-14 08:41:59 +0800 CST

SQL Server - 窗口查询中的标准偏差

  • 1

SQL Server 提供了该STDEV函数,但它不能与窗口函数一起使用。

例如

SELECT
     TestName
    ,[BatchSize]
    ,[NumIterations] = COUNT(*)
    ,[Min] = MIN(RuntimeMs)
    ,[Average] = AVG(RuntimeMs)
    ,[Max] = MAX(RuntimeMs)
    ,[StdDev] = STDEV(RuntimeMs)
FROM #TimingResult
GROUP BY TestName, [BatchSize]

如何同时计算百分位数和标准差?

sql-server
  • 1 个回答
  • 682 Views
Martin Hope
Elaskanator
Asked: 2018-06-14 06:37:47 +0800 CST

SQL Server - 将 LOG 结果截断为整数时出现不一致的隐藏机器精度错误

  • 4

在将 1000 的以 10 为底的对数转换为整数时,我注意到 SQL Server(至少 2008R2)中存在一些奇怪的舍入行为。答案显然是精确值 3,但 SQL 服务器在输出中隐藏了一些小数:

SELECT LOG(1000, 10)--returns 3 with no visible decimals
SELECT CONVERT(INT, LOG(1000, 10))--returns 2

我对最小 epsilon 进行了逆向工程,以便在将其添加到LOG转换前的结果中时获得正确的值,大致如下:

SELECT CONVERT(INT, LOG(1000, 10)+0.0000000000000002220446049250313)
SELECT CONVERT(INT, LOG(1000, 10)+0.0000000000000002220446049250312)

在此处输入图像描述

看来我可以整天继续使这个值更精确。

这似乎仅对于 1000 的情况是必要的,因为我在不使用任何 epsilon 项的情况下获得了 1、10、100 和 10000 以及更大的正确整数值。

错误项似乎是泰勒级数的尾部扩展了 16 个项(根据此页面),但是当我尝试针对 10000 和更大的情况时,为什么 SQL Server 突然按预期运行(没有隐藏的机器精度错误) ?

为什么 SQL Server不一致地显示机器精度错误?

谢谢。

sql-server
  • 2 个回答
  • 521 Views
Martin Hope
Elaskanator
Asked: 2018-06-02 12:07:33 +0800 CST

SQL Server - 将不可为空的列添加到现有表 - SSDT Publishing

  • 16

由于业务逻辑,我们需要在表中添加一个新列,以确保始终填充该列。因此,应将其添加到表中NOT NULL。与之前解释如何手动执行此操作的问题不同,这需要由 SSDT 发布管理。

由于一些认识,我一直在为这个听起来很简单的任务撞墙一段时间:

  1. 默认值不合适,它不能是计算列。也许它是一个外键列,但对于其他列,我们不能使用像 0 或 -1 这样的假值,因为这些值可能有意义(例如数字数据)。
  2. 在预部署脚本中添加列将在第二次自动尝试创建同一列时使发布失败(即使预部署脚本被编写为幂等的)(这真的很严重,否则我可以想一个简单的解决方案)
  3. 在部署后脚本中将列更改为 NOT NULL 将在每次 SSDT 架构刷新发生时恢复(因此至少我们的代码库将在源代码控制和服务器上的实际内容之间不匹配)
  4. 现在将列添加为可为空以在将来更改为 NOT NULL 不适用于源代码控制中的多个分支/分支,因为目标系统在下次升级时不一定都具有相同状态的表(无论如何,这并不是一个好方法IMO)

听别人说的做法是直接更新表定义(这样架构刷新是一致的),写一个预部署脚本,将表的全部内容移动到一个临时表中,包含新的列填充逻辑,然后移动后部署脚本中的行。不过,这似乎很冒险,并且当它检测到一个 NOT NULL 列被添加到具有现有数据的表中时(因为验证在预部署脚本之前运行),它仍然会惹恼发布预览。

我应该如何添加一个新的、不可为空的列而不冒孤立数据的风险,或者在每次发布时使用本来就有风险的冗长迁移脚本来回移动数据?

谢谢。

sql-server scripting
  • 1 个回答
  • 7115 Views
Martin Hope
Elaskanator
Asked: 2018-05-17 09:15:58 +0800 CST

SQL Server 代理似乎以不同方式对待 sysprocesses(和 dm_exec_sessions)

  • 0

我有一个通过 SQL 代理作业运行的看门狗进程来管理一些自定义任务。其中一项检查是该进程不再存在:

UPDATE R
SET IsOrphaned = 1, DebugTimestampUtc = GETUTCDATE()
FROM
    RequestTable AS R
    LEFT JOIN sys.sysprocesses AS P ON
        P.spid = R.SPID
WHERE P.spid IS NULL

在 SSMS 中,我运行此语句然后在它完成之前关闭查询窗口(取消查询):

INSERT INTO RequestTable(SPID, CreateTimestampUtc, ...)
SELECT @@SPID, GETUTCDATE(), ...
WAITFOR DELAY '00:00:30.000'

当我手动运行查询以在 SSMS 中标记孤儿时,它在行上匹配,但我的工作没有,因为RequestTable没有将行标记为孤儿。作业历史记录显示它按计划运行,没有任何错误,运行时间可以忽略不计(< 1 秒)。

此外,当我增加孤儿检测语句时,它还会在我取消查询(并保持查询窗口打开)P.status = 'sleeping'时立即检测到的记录中找到记录。INSERT ... WAITFOR ...

SQL Server 是否有一些微妙的行为导致sys.sysprocessesSSMS 和 SQL Agent 之间的表出现这种明显不一致的状态?我也尝试过使用和不使用 NOLOCK 查询提示RequestTable。

我在 SQL Server 2014 上以 2008R2 的兼容模式运行。

(请注意,使用sys.dm_exec_sessionsinstead 仍然表现相同)

谢谢。

PS 这样做的目的是序列化存在并发问题的异步进程。也许还有更好的方法来做到这一点(无法修复异步进程)?

sql-server ssms
  • 1 个回答
  • 150 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