【问题标题】:Why can't I enter a NULL value using Numeric or Date type in Postgresql?为什么我不能在 Postgresql 中使用数字或日期类型输入 NULL 值?
【发布时间】:2012-08-10 07:23:13
【问题描述】:

我正在为这项工作做一个小申请,其中包括一个表格。当使用表单的人没有在数据类型“数字”(比如说 PIN 码)中输入值,甚至没有在我的“日期”数据类型字段之一中输入日期(比如说他的周年纪念日)时,它会返回给我错误如下:

错误类型 – 错误类型 _用于 ODBC 驱动程序的 Microsoft OLE DB 提供程序 (0x80004005)_ 错误:数字类型的输入语法无效:“”;执行查询时出错

错误类型 – 错误类型 _用于 ODBC 驱动程序的 Microsoft OLE DB 提供程序 (0x80004005)_ 错误:“)”处或附近的语法错误;执行查询时出错

所以看起来当使用表单的人什么都不输入时,它返回字符串“empty”,即“”。 为什么数字类型和数据类型不能将其读取为 NULL 条目?这些字段不是强制性的,因此有时我需要将它们留空。

我怎样才能使它成为可能?他们是一种继续使用“数字”和“日期”类型的方法,以便当用户在这些字段中不输入任何内容时,表格会填充一个空白大小写,指示给我这个错误?

这是我的sql语句:

trsConn.EXECUTE "INSERT INTO ""TRS"".employeetbl ( "& _
  """firstName"", " & _  
  """lastName"" , " & _  
  """detContract"", " & _  
  "sle, " & _  
  """posNumber"" "& _  
  ") VALUES (" & _  
  "'" & Request.Form("empFirst") & "', " & _**  
  "'" & Replace(Request.Form("empLast"), "'", "`") & "', " & _  
  "'" & Request.Form("dateContract") & "', " & _
  "'" & Request.Form("sle") & "', " & _  
  "'" & Request.Form("posNum") & "');"  

(posNum 和 dateContract 分别属于“numeric”和“date”类型

非常感谢您的帮助。期待听听各位天才的说法。

【问题讨论】:

  • 哇。 “ASP 经典”是否支持占位符准备好的语句?我怀疑 一个 的问题是它正在对数据进行插值,所以它最终会像 .. VALUES (.., 'NULL', ..) 而不是应该是 .. VALUES (.., NULL, ..)
  • 另外,为什么posNum 使用(一个有趣的单引号,这是错误的)而其他人使用'(撇号,这是正确的)?您可以为posNum 输入any 值吗? (也就是说,标题是红鲱鱼吗?)
  • 这是经典的'"" 不等于NULL'。 NULL 永远不等于任何东西,你不能用任何东西代替它(好吧,我不能说永远 - Oracle 多年来一直是个例外)。如果要分配NULL,请分配NULL。如果要查看某列是否为NULL,请使用IS NULL;他们有IsNull()Coalesce() 专门用于处理NULL 值——这就是为什么他们有特殊的功能和一个操作员来检查它。 NULL 其他,没有其他 = NULL.
  • @pst:我很确定它使用的是'' 而不是'NULL',它应该只使用文字NULL
  • 顺便说一句,使用经典 SQL 驱动程序的 ASP 确实支持准备好的语句:stackoverflow.com/questions/8538979/…。文斯,考虑使用准备好的语句,为了可读性,为了你周围所有人的理智,为了可怜的 Bobby Tables xkcd.com/327

标签: postgresql asp-classic vbscript postgresql-9.0


【解决方案1】:

The concept of NULL in SQL is pretty muddled and inconsistent ... 但很明显''NULL 不同。

'' 不是NULL,而是'',空字符串。您不能将其转换为日期、数字等:

regress=# SELECT CAST('' AS DATE);
ERROR:  invalid input syntax for type date: ""
LINE 1: SELECT CAST('' AS DATE);
                    ^
regress=# SELECT CAST('' AS NUMERIC);
ERROR:  invalid input syntax for type numeric: ""
LINE 1: SELECT CAST('' AS NUMERIC);
                    ^

一些产品——尤其是 Microsoft Access 和旧版本的 MySQL——对这个问题感到困惑。 NULL 为 NULL,'' 为空字符串;他们不是一回事。您不能将一个转换为另一个。

所以看起来,当使用表单的人什么都不输入时,它 返回字符串“empty”,即“”。为什么数字类型不能和 数据类型读取为 NULL 条目?这些字段不是强制性的 所以我需要让它们有时是空白的。

这是您的应用程序的工作。当您的应用程序看到空字符串出现在数字、日期或类似的表单字段中时,它应该将NULL 发送到数据库,而不是''。这通常是在将数据提供给数据库之前从用户输入转换数据的常规部分。您进行这种转换是至关重要的;你不应该只是将用户的值直接发送到数据库。

快速搜索表明 asp classic 使用 nullundefined 作为其空值;当某些内容为空时,您应该能够将它们传递到您准备好的语句中。

在出现关于'' 的错误之后出现语法错误这一事实表明,您将SQL 语句构建为字符串,而不是使用prepared statements with placeholders。 (感谢 JayC 的 SO 问题参考)。这是乞求SQL injection;换句话说,您的应用程序极度不安全。想象一下如果用户输入“日期”会发生什么:

2012-01-01'); DROP SCHEMA public;--

你的应用程序很乐意将其变成

INSERT INTO sometable (blah, blah, blah) VALUES (1, 2, DATE '2012-01-01'); DROP SCHEMA public;--');

DROP SCHEMA 然后愉快地执行,哎呀,啪,你的数据库到了。这也是最愚蠢、最简单的一种 SQL 注入攻击。

【讨论】:

  • 非常感谢克雷格!一切都让我大开眼界,真的很感激。另外,我意识到我的应用程序不安全,但它仍在开发中,除了我之外没有人真正可以访问它。它也不能通过 Internet 访问,因为它的用户将来自我机构的 Intranet 页面。再次感谢!
  • @Vince.CRA IMO 是从一开始就在编写时确保其安全的最佳时机。完成后,安全性不是一个附加组件,如果您想让它模糊正确,您需要在设计、工具选择、部署时考虑它。至于不在互联网上 - 确保攻击面较低,但只需要一名好奇/心怀不满的员工(或配置错误的代理服务器)即可。有一些工具可以让任何人都可以利用简单的 SQL 注入漏洞。
  • @Vince.CRA 另外,说真的,您正在用 ASP 经典开发一个应用程序?这是一个……有趣的……决定。那将如何支持?
猜你喜欢
  • 1970-01-01
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
  • 2021-02-03
  • 2011-02-09
相关资源
最近更新 更多