2010-05-18 51 views
2

我有一个查询Postgres的柱铸造

SELECT assetid, type_code, version, name, short_name, status, languages, 
charset, force_secure, created, created_userid, updated, updated_userid, 
published, published_userid, status_changed, status_changed_userid 
FROM sq_ast WHERE assetid = 7 

不工作,并抛出

ERROR: operator does not exist: character varying = integer LINE 4: FROM sq_ast WHERE assetid = 7 

我可以让它做

SELECT assetid, type_code, version, name, short_name, status, languages, 
charset, force_secure, created, created_userid, updated, updated_userid, 
published, published_userid, status_changed, status_changed_userid 
FROM sq_ast WHERE assetid = '7' 

工作,请注意报价WHERE子句中的7 ...

我正在部署一个巨大的应用程序,我不能改写核心...同样我不想冒险改变列的类型...

我不是Postgres专家...请帮助.. 。

是否有严格铸造柱的选项?

+0

哪个PostgreSQL版本?一个快速测试表明8.4允许这样做。 – araqnid 2010-05-18 19:17:57

回答

6

Postgresql在最近的版本中输入得更强,这是一件好事。如果assetid是VARCHAR,那么你不能将它与一个整数相比较(我认为从8.4开始)。

一般来说(不仅在Postgresql中,不仅在数据库设计中)混合这些类型的设计很糟糕:数字数据类型应该用于真正的数字字段,而不是用于恰好包含数字的字符串。

例如,发票“号码”或信用卡“号码”通常不应表示为“号码”,而应表示为字符串。

然而,有时候,这个决定并不明确(例如:文件编号)。

一些标准,可以帮助:

  • 你在做算术你的价值观可能有兴趣(总和。减去)?至少这是否合理?然后,这是一个number

  • 应该零左被保留,或认为相关? ('07'被认为与'7'不同?)然后,它是一个string

根据您在您的方案anwser这些问题(是否有从0开始的由assetid?难道还有一些非数字字符?它似乎是一个序列号?),你可能会考虑到更改字段类型或(在您的情况更可能)做一个演员,在首选方向:

SELECT... FROM sq_ast WHERE assetid::integer = 7 

(如果你决定该字段是数字)或其他地方

SELECT... FROM sq_ast WHERE assetid = '7' 

没有用于恢复旧行为的全局设置,并强制对字符类型AFAIK进行隐式转换。

+0

“没有恢复到旧行为的全局设置” - 在[另一个答案]上找到(http:// stackoverflow。com/a/18129968/243245),你可以创建隐含的强制转换函数来模仿旧的行为,例如使用[PostgreSQL维基上的脚本](http://wiki.postgresql.org/wiki/Image:Pg83-implicit-casts.sql)。 – Rup 2014-03-05 18:38:18