SQL Server 2005:“保护”存储过程免受 MS Access 使用的 FMTONLY 模式影响

2024-04-30

我们拥有的一些存储过程包含条件逻辑,如下所示:

Create Procedure dbo.DoSomething(Some Parameters)
As
    ...
    If (Some Condition) Begin
        Set @SomeVariable = SomeValue                
    End
    ...
    Select ...

当这样的存储过程用作 MS Access 表单的记录源,并且用户尝试使用表单的内置排序/过滤功能时,MS Access 会尝试以 FMTONLY 模式执行存储过程(显然,寻找存储过程提供的行集)。

大多数人都知道(现在包括我们自己:-),当 FMTONLY 设置为 ON 时,SQL Server 会忽略条件语句。在下面所示的示例中,Set @SomeVariable = SomeValue无论是否执行语句Some Condition确实如此,这显然给我们带来了一些麻烦。

-- EXAMPLE
-- -------
Create Procedure dbo.DoSomething(..., @vcSomeDate as VarChar(50), ...)
As
   ...
   Declare @dtSomeDate As Datetime
   If (IsDate(@vcSomeDateOrAgeInDays)) Begin
       -- The next statement fails miserably when FMTONLY=ON
       Set @dtSomeDate = @vcSomeDateOrAgeInDays
   End Else Begin
       ...
   End
   ...

为了规避这个问题,我们“包装”条件逻辑(或受 FMTONLY 影响的任何其他代码片段),如下所示:

Create Procedure dbo.DoSomething(Some Parameters)
As
    ...

    -- HACK: Protection from unexpected FMTONLY mode
    Declare @wasFmtonlyOn As Bit; If (0 = 1) Set @wasFmtonlyOn = 1; SET FMTONLY OFF
    ...
    If (Some Condition) Begin
        Set @SomeVariable = SomeValue                
    End
    ...
    -- /HACK: Protection from unexpected FMTONLY mode
    If (@wasFmtonlyOn = 1) SET FMTONLY ON

    ...
    Select ...

(“保护代码”的这种丑陋的一行格式是故意的:我们认为解决一些奇怪问题所需的黑客不值得正确的格式;恰恰相反,我们认为它们应该适合尽可能少的代码行.:-)

无论如何,这种“保护”效果很好,但它有点过于冗长,并且没有我们希望的那么封装。例如,我们肯定更愿意隐藏黑客的实际逻辑 - 例如隐藏在标量 UDF 后面,如下所示:

Create Procedure dbo.DoSomething(Some Parameters)
As
    ...

    declare @wasFmtonlyOn as bit; set @wasFmtonlyOn = dbo.SetFmtonly(0)
    ...
    If (Some Condition) Begin
        Set @SomeVariable = SomeValue                
    End
    ...
    dbo.SetFmtonly(@wasFmtonlyOn)

    ...
    Select ...

不幸的是,这似乎不起作用——无论是对于标量 UDF,还是另一个存储过程。看起来 FMTONLY 可以防止从任何地方返回任何数据。那么,来了主要问题:

如果您也必须处理这个问题(SQL Server 在 FMTONLY 模式下忽略条件),您是否能够想出比上述更好的“保护习惯用法”?

顺便说一句,我仍然不明白一件事:这个问题是 SQL Server 2005 中的错误还是功能?如果它是一个功能,那么它的充分理由是什么?

谢谢你!


那这个呢?

If (Some Condition) Begin
    Set @SomeVariable = SomeValue
ELSE
    Set @SomeVariable = @SomeVariable --or dummy/default value?
End

您的代码是否根据此变量返回 2 个不同的记录集(列和类型)? 如果是这样,你必须将存储过程分成 2 个

另外,我还发现了一个知识库文章 http://support.microsoft.com/?kbid=933248这就解释了为什么。

编辑: 将分支更改为内联代码...

Set @dtSomeDate = CASE WHEN ISDATE(@vcSomeDateOrAgeInDays) = 1 THEN @vcSomeDateOrAgeInDays ELSE NULL END
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL Server 2005:“保护”存储过程免受 MS Access 使用的 FMTONLY 模式影响 的相关文章

随机推荐

  • 下面的代码是如何工作的?

    众所周知 cout 在 VS2010 中是无缓冲的 参见 Stephan Lavavej 的帖子 here http connect microsoft com VisualStudio feedback details 642876 st
  • 是否可以将 RSA Archer 与多个 Active Directory 集成?

    是否可以将 RSA Archer 与多个 Active Directory 集成 一切皆有可能 只是你愿意付出多少努力 Option 1 推荐 RSA Archer v5 x 支持多种 LDAP 同步配置 因此 您可以拥有多个 AD 服务器
  • 使用 python 登录 Instagram 时出错

    我正在尝试使用 argparse 通过 python 脚本登录我的 Instagram 似乎已连接 但打印出 无法加载该页面 如果您的浏览器禁用了 cookie 或者您正在以私人模式浏览 请尝试启用 cookie 或关闭私人模式 然后重试您
  • 有没有办法让特定的 div 忽略它的父 div 的位置?

    我有一个 div 其位置因其包含的 div 的相对定位而偏离 虽然删除父级的相对定位可以解决问题 但我们宁愿不将其作为解决方案来实现 因为它可能会破坏其他内容 有没有办法强迫孩子忽略父母的定位 不幸的是 没有办法让一个元素通过 CSS 动态
  • 合并来自 ffmpeg 的两个视频

    我想使用 ffmpeg 将两个 mp4 视频组合成一个 mp4 视频 到目前为止我尝试过的是 ffmpeg i input1 mp4 i input2 mp4 output mp4 但是 每次我获取带有第一个输入的视频编解码器的视频而不是另
  • iPhone X - 设置主页指示器周围区域的颜色

    当我尝试将工作表与 iPhone X 的安全区域对齐时 我对 Xcode 还很陌生 它在工作表下方留下了一个透明区域 有没有办法设置该区域的填充而不扩展纸张或在安全区域之外对齐 这是我的小扩展 如果有人可以建议改进以不通过 幻数 标签访问添
  • 如何找到与一个变量中的最大值相对应的所有变量的最大值?

    我有一个包含许多变量的每日数据 xarray 我想提取最大q routed每年及最大当日其他变量的对应值q routed发生
  • 什么是 NullPointerException,如何修复它?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 什么是空指针异常 java lang NullPointerException 以及是什
  • 了解 C++0x lambda 捕获

    在最近的一份 C 0x 草案 n3225 pdf 中 我们可以找到 5 1 2 10 使用非限定名称查找的常用规则来查找捕获列表中的标识符 3 4 1 每个此类查找都应找到在本地 lambda 表达式的到达范围中声明的具有自动存储持续时间的
  • 如何查询 USB Root Hub 中未列出的 USB 设备

    查询适用于在以下位置找到的某些设备Win32 USBHub SELECT FROM Win32 USBHub WHERE DeviceID 0 这是代码上下文 Check if USB device is plugged in string
  • 如何在 Mongoose 中使用正则表达式查找项目[重复]

    这个问题在这里已经有答案了 在 Mongoose 文档中我没有找到等效的 regex https docs mongodb com manual reference operator query regex MongoDb 的 你能提供一个
  • 使用 KDE Kirigami 时未找到 QML 模块

    所以我决定在我的应用程序中使用 KDE Kirigami UI 框架 所以我按照说明进行操作here https api kde org frameworks kirigami html index html 我将存储库克隆到我的应用程序目
  • 另一个 MinGW“gcc:错误:CreateProcess:没有这样的文件或目录”

    我已经通过 GUI 安装程序在 Windows 8 64 位 中安装了 MinGW C 编译器 但是当我尝试编译 C 程序时 gcc 说 gcc CreateProcess 没有这样的文件或目录 这是一个常见的错误 我已经尝试了我找到的所有
  • 查找数组中的 K 个最小值(堆 vs QuickSelect)

    假设我们有一个数组 我们希望找到它的 K 个最小值 有两种方法 1 使用快速选择算法 O n 时间复杂度和O 1 空间 2 使用最小堆数据结构 O NlogK 时间复杂度和O K 空间 我想知道什么时候一个比另一个更受青睐 我想这两个都可以
  • 如何实现有效的 Java 特征?

    请告诉我这是否不合适 特别是 Programmers SE 或其他东西是否更适合这个问题 好吧 因此 我目前将许多 特征 表达为接口 我们称它们为 可更新 和 可破坏 将它们表达为接口的缺点是我无法在所有 可破坏 组件之间共享行为 另一方面
  • 用 C 将位写入文件

    我有这个字符串 101 我想用 C 语言将其写入文件 而不是文本 101 等 8 位 x 字符 但直接使用字符串作为位 位 1 位 0 和位 1 这样文件将是3位 有可能吗 我在网上搜索并尝试这样做 char c 25 101 FILE b
  • 在 Vue.js 中,如何防止子路由的导航?

    好的一点是beforeRouteLeave是你可以防止在某些情况下导航离开 我有一个使用子路由来渲染页面的一部分的设置 我希望在子路线上设置一个导航守卫 以防止在未保存数据的情况下切换到另一条路线 path customers view c
  • 如何在 JIRA Script Runner 中通过电子邮件获取用户

    编写 Groovy 脚本时JIRA 脚本运行器 https marketplace atlassian com plugins com onresolve jira groovy groovyrunner server overview 如
  • CGAL:从网格中读取顶点和三角形

    我只是花了几个小时在 Visual Studio C 中使用 CGAL 来尝试了解网格的工作原理 我想要得到的是对顶点和三角形列表的访问 顶点以 double 3 形式 三角形以 int 3 形式 这是我正在编写的脚本 http doc c
  • SQL Server 2005:“保护”存储过程免受 MS Access 使用的 FMTONLY 模式影响

    我们拥有的一些存储过程包含条件逻辑 如下所示 Create Procedure dbo DoSomething Some Parameters As If Some Condition Begin Set SomeVariable Some