SQL 更新可选参数 PHP

2024-01-31

我们想要改变将值从 PHP 传递到存储过程 (T-SQL) 的方式。我对 PHP 只有很少的经验,但我将尝试通过与我们的 Web 开发人员的讨论来解释该过程。

当前流程

测试表示例

为了更新记录(例如本示例中的 Field3),我们会将所有现有值传递回存储过程。

EXEC dbo.UpdateTest @ID = 1, @Field1 = 'ABC', @Field2 = 'DEF', @Field3 = 'GHI', @Field4 = 'JKL'

假设要更新 Field3,您必须单击一个按钮。这将导航到一个新页面,该页面将运行存储过程来更新数据。由于新页面不知道它必须运行的值SELECT在运行之前检索值的过程UPDATE.

然后,脚本会将用户重定向回重新加载更新数据的页面,并且更改会反映在屏幕上。

新工艺

我们想要做的只是传递我们想要更改的字段。

EXEC dbo.UpdateTest @ID = 1, @Field2 = 'DEF', @Field3 = 'GHI'

我们的解决方案很简单。首先,我们将所有可更新字段设置为可选(因此NULL可以通过)。然后我们检查参数是否为NULL(未通过),如果是,则我们忽略它,如果不是,我们更新它。

UPDATE 
    dbo.Test
SET
    Field1 = NULLIF(ISNULL(@Field1,Field1),'-999')
    ,Field2 = NULLIF(ISNULL(@Field2,Field2),'-999')
    ,Field3 = NULLIF(ISNULL(@Field3,Field3),'-999')
    ,Field4 = NULLIF(ISNULL(@Field4,Field4),'-999')
WHERE
    ID = @ID

但是我们仍然希望该过程将数据库记录更新为NULL if a NULL value is通过了。解决这个问题的方法是将任意值分配给 equalNULL(在本例中为-999),以便程序将更新NULL如果传递任意值(-999)。

这个解决方案相当混乱,在我看来,这是解决问题的低效方法。还有更好的解决方案吗?我们做错了什么?

非常感谢您的回复


就传递标志变量来识别值何时传递或不传递而言,Valdimir 的方法很棒,而且他关于任意选择值的注释是正确的,但我猜想有一些任意值你可能永远不必担心。例如,当不允许负数时,整数为 -999,或“|||||||”对于空字符串。当然,当您确实想使用负数时,这会破坏一些功能,但是您可能会使用对于数据类型来说太大的数字,例如 BIGINT 作为 int 的参数默认值 -9223372036854775808 ....问题确实如此根据您的业务案例确定值是否可以被允许。

然而,如果你走这样的路线,我会建议两件事。 1) 不要将值从 PHP 传递到 SQL,而是将其设置为 SQL 中的默认值,并测试参数是否为默认值。 2)向表添加CHECK CONSTRAINT以确保值不被使用并且不能在表中表示

所以像这样:

ALTER TABLE dbo.UpdateTest
CHECK CONSTRAINT chk_IsNotNullStandInValue (Field1 <> '|||||||||||||||||||' AND Field2 <> -999)

CREATE PROCEDURE dbo.UpdateTest
    @ParamId numeric(10,0)
    ,@ParamField1 NVARCHAR(250) = '|||||||||||||||||||'
    ,@ParamField2 INT = -99999  --non negative INT
    ,@ParamField3 BIGINT = -9223372036854775808 --for an int that can be negative
AS
BEGIN

DECLARE @ParamField3Value INT

BEGIN TRY

    IF ISNULL(@ParamField3,0) <> -9223372036854775808
    BEGIN
       SET @ParamField3Value = CAST(@ParamField3 AS INT)
    END
END TRY
BEGIN CATCH
    ;THROW 51000, '@ParamField3 is not in range', 1
END CATCH

    UPDATE dbo.Test
       SET Field1 = IIF(@ParamField1 = '|||||||||||||||||||',Field1,@ParamField1)
          ,Field2 = IIF(@ParamField2 = -99999,Field2,@ParamField2)
          ,Field3 = IIF(@ParamField3 = -9223372036854775808, Field3, @ParamField3Value)
    WHERE
       ID = @ParamId

END

此方法的真正问题是数字数据字段允许负数,因为您实际上没有适当的方法来确定该值何时应为空或不为空,除非您可以选择一个始终超出范围的数字。我绝对意识到 BIGINT for INT 示例是多么糟糕的想法,因为现在您的程序将接受不应该接受的数字范围!

弗拉基米尔建议的另一种方法/略有变化是标记何时使字段为空而不是何时更新。您的 PHP 团队需要花一点时间来习惯如何记住使用,但因为这些标志也可以是可选的,因此它们不必总是包含以下内容而成为负担:

CREATE PROCEDURE dbo.UpdateTest
    @ParamId numeric(10,0)
    ,@ParamField1 NVARCHAR(250) = NULL
    ,@MakeField1Null BIT = 0
    ,@ParamField2 INT = NULL
    ,@MakeField2Null BIT = 0
    ,@ParamField3 INT = NULL
    ,@MakeField3Null BIT = 0
AS
BEGIN

    UPDATE dbo.Test
       SET Field1 = IIF(ISNULL(@MakeField1Null,0) = 1,NULL,ISNULL(@ParamField1,Field1))
          ,Field2 = IIF(ISNULL(@MakeField2Null,0) = 1,NULL,ISNULL(@ParamField2,Field2))
          ,Field3 = IIF(ISNULL(@MakeField3Null,0) = 1,NULL,ISNULL(@ParamField3,Field3))
    WHERE
       ID = @ParamId

END

基本上,如果您使用存储过程来更新表并且它具有可为空的字段,我认为我不建议将参数设置为可选,因为它会导致将来可能会变得混乱的业务案例/情况,特别是对于数字数据类型!

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

SQL 更新可选参数 PHP 的相关文章

随机推荐

  • 命名空间“std”中没有名为“unary_function”的模板;您的意思是“__unary_function”吗?

    刚刚将我的 Xcode 升级到 15 0 突然它开始在 RCT Folly 中出现以下错误 No template named unary function in namespace std did you mean unary funct
  • 在运行时转储 gcov 数据

    我正在使用 gcov 收集我正在从事的 C 项目的代码覆盖率数据 据我所知 一旦程序完成后退出 gcov 就会转储代码覆盖率数据 如何收集长时间运行的进程的 gcov 数据 比如说 我的程序是一个操作系统的内核 该操作系统在永不关闭的服务器
  • iOS:Xcode 中的 ImageMagick 编译器警告

    我在 iOS 项目中使用 ImageMagick 但是该库已经过时 因为以前的开发人员使用了源代码 我使用的是 Xcode 6 3 2 我想使用 Cocoapods 将 ImageMagick 集成到项目中 而不是复制源文件 然而 当我将
  • SDL_ttf找不到“SDL.h”,但main.cpp可以

    我正在编写一个 make 文件来编译一个非常简单的 SDL2 程序 到目前为止 它编译 SDL2 得很好 现在我正在编译扩展框架 SDL2 image 和 SDL ttf 看起来MAKE正确地找到了SDL ttf h 但是SDL ttf h
  • 使用 GSON 将 JSON 转换为 Java 对象时如何覆盖 Java 映射?

    我有一个 JSON 字符串 如下所示 status status date 01 10 2019 alerts labels field1 value1 field2 value2 field3 value3 field100 value1
  • Sphinx Note Block 在代码块下的列表中?

    我有一个问题 如果我想将注释块放在代码块下的列表中 它就会包含在代码块中 如果我取消缩进 列表编号会在注释后重新开始 所以基本上 我需要的是 Fixed list example First do spam Then do eggs som
  • 如何使用 BERT 找到与向量最接近的单词

    我正在尝试使用 BERT 获取给定单词嵌入的文本表示 或最接近的单词 基本上我试图获得与 gensim 类似的功能 gt gt gt your word vector array 0 00449447 0 00310097 0 024217
  • 谷歌的无图像按钮

    最近有几篇关于谷歌新的无图像按钮的文章 http stopdesign com archive 2009 02 04 recreating the button html http stopdesign com archive 2009 0
  • 将文本添加到绘图中

    x lt seq 3 3 0 01 y1 lt dnorm x 0 1 y2 lt 0 5 dnorm x 0 1 plot x y1 type l bty L xlab X ylab dnorm X points x y2 type l
  • 数组中所有元素的总和

    我是编程初学者 我想计算数组中所有元素的总和 我做了这个 但我看不出我的错误在哪里 function ArrayAdder array this sum 0 this array array ArrayAdder prototype com
  • python 按不同标准对元组进行排序

    我有一个清单a 1 a 1 b 2 c 我想得到这个列表 2 c 1 a 1 b 如果我这样做 sorted a reverse True 我只能得到 2 c 1 b 1 a 我怎样才能得到我想要的列表 如果您想保留原始列表中的排序顺序 但
  • 如何通过 SoundCloud API 添加评论

    我想通过 SoundCloud API 发表评论 但查看文档 http developers soundcloud com docs api reference tracks这似乎是不可能的 唯一可用的方法 tracks id commen
  • 为什么 React 需要 Babel 和 Webpack 才能工作?

    我正在查看 vue js 的 wiki 页面 看到了这个 与 React 开发相比 Vue 可以集成到 现有的 Web 应用程序更加容易 通常 Web 应用程序 只需包含 Vue js 即可立即开始使用 Vue JavaScript 库 与
  • ASP.NET MVC 中的超快速文本到语音 (WAV -> MP3)

    这个问题本质上是关于微软的语音API SAPI 对于服务器工作负载的适用性以及它是否可以在内部可靠地使用 w3wp用于语音合成 我们有一个异步控制器 它使用本机System Speech NET 4 中的程序集 不是Microsoft Sp
  • 如何刷新 Google OAuth2 AccessToken

    我见过很多问题 https stackoverflow com questions 22357348 google apis client for csharp auth using refresh token关于这个问题有不同的答案 有些
  • 一次循环遍历 2 个列表

    我有两个长度相同的列表 是否可以同时循环这两个列表 我正在寻找正确的语法来执行以下操作 foreach itemA itemB in ListA ListB Console WriteLine itemA ToString itemB To
  • 如何对向量列表执行成对运算(如“%in%”)和集合运算

    这个问题的动机是如何快速查看 R 中多个向量的任何元素是否相等 https stackoverflow com q 39060567 4891738 但不相同 重复 作为一个小例子 假设我们有一个包含 4 个向量的列表 set seed 0
  • 通过 wsHttpBinding 在 PHP 中调用 WCF WebService

    我有一个 WCF Web 服务 我可以通过 basicHttp 连接到它 但不能通过 wsHttp 连接到它 我尝试通过以下方式通过 wshttp 连接到它 service new SoapClient http service compa
  • Angular 5 Service Worker 不工作/不缓存背景图像

    我无法让我的 Angular5 Service Worker 工作 我有两个主要问题 Service Worker 不会缓存用作背景图像的资产图像 模拟网络断开连接后 服务工作人员最初从缓存中提取文件 上述非缓存文件除外 但在第二次刷新后会
  • SQL 更新可选参数 PHP

    我们想要改变将值从 PHP 传递到存储过程 T SQL 的方式 我对 PHP 只有很少的经验 但我将尝试通过与我们的 Web 开发人员的讨论来解释该过程 当前流程 测试表示例 为了更新记录 例如本示例中的 Field3 我们会将所有现有值传