Sql Postgres:为强制转换失败定义默认值?
是否可以定义在Sql Postgres:为强制转换失败定义默认值?,sql,postgresql,Sql,Postgresql,是否可以定义在CAST操作失败时返回的默认值 例如,以便: SELECT CAST('foo' AS INTEGER) 将返回默认值而不是抛出错误?按照文档中的说明捕获错误,然后指定要执行的操作 下面包含的代码片段 35.7.5。陷阱错误 默认情况下,PL/pgSQL函数中发生的任何错误都会中止函数的执行,事实上也会中止周围事务的执行。通过使用带有EXCEPTION子句的BEGIN块,可以捕获错误并从中恢复。该语法是BEGIN块正常语法的扩展: [ <<label>>
CAST
操作失败时返回的默认值
例如,以便:
SELECT CAST('foo' AS INTEGER)
将返回默认值而不是抛出错误?按照文档中的说明捕获错误,然后指定要执行的操作 下面包含的代码片段 35.7.5。陷阱错误 默认情况下,PL/pgSQL函数中发生的任何错误都会中止函数的执行,事实上也会中止周围事务的执行。通过使用带有EXCEPTION子句的BEGIN块,可以捕获错误并从中恢复。该语法是BEGIN块正常语法的扩展:
[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements
EXCEPTION
WHEN condition [ OR condition ... ] THEN
handler_statements
[ WHEN condition [ OR condition ... ] THEN
handler_statements
... ]
END;
[]
[宣布
声明]
开始
声明
例外情况
当条件[或条件…]出现时
handler\u语句
[当条件[或条件…]然后
handler\u语句
... ]
结束;
如果没有发生错误,这种形式的块只执行所有语句,然后控制权在结束后传递到下一个语句。但如果语句中发生错误,则放弃对语句的进一步处理,并将控制传递到异常列表。将在列表中搜索与发生的错误匹配的第一个条件。如果找到匹配项,则执行相应的handler_语句,然后控制传递到END后的下一个语句。如果找不到匹配项,则错误会向外传播,就好像EXCEPTION子句根本不存在一样:包含异常的封闭块可以捕获错误,或者如果没有异常,则会中止函数的处理。没有以下项的默认值: 类型转换指定从一种数据类型到另一种数据类型的转换。PostgreSQL接受类型转换的两个等效语法:
CAST ( expression AS type )
expression::type
除了要强制转换的表达式和所需的目标类型之外,语法中没有其他空间
但是,您可以通过一个简单的功能手动完成:
create or replace function cast_to_int(text, integer) returns integer as $$
begin
return cast($1 as integer);
exception
when invalid_text_representation then
return $2;
end;
$$ language plpgsql immutable;
然后你可以说类似于cast\u to_int('pancakes',0)
的话,然后得到0
PostgreSQL还允许您执行以下操作:
create or replace function cast_to_int(text) returns integer as $$
begin
-- Note the double casting to avoid infinite recursion.
return cast($1::varchar as integer);
exception
when invalid_text_representation then
return 0;
end;
$$ language plpgsql immutable;
create cast (text as integer) with function cast_to_int(text);
那么你可以说
select cast('pancakes'::text as integer)
select cast(some_text_column as integer) from t
然后得到0
,或者你可以说
select cast('pancakes'::text as integer)
select cast(some_text_column as integer) from t
并为某些\u text\u列
中无效整数的值获取0
。如果要使用此自动默认强制转换来强制转换varchar
s,则必须加倍强制转换:
select cast(some_varchar::text as integer) from t
仅仅因为你能做到这一点并不意味着这是一个好主意。我不认为将标准文本替换为整数强制转换是有史以来最好的主意。上述方法还要求您将标准的varchar
转换为integer
,如果您想自己完成整个转换,而不是懒洋洋地将其转换为内置转换,您可以绕过这一点
空处理留给读者作为一个(简单的)练习。以这种方式更改默认/预期行为让我觉得。。。危险的您希望能够使用类似于
IS\u NUMERIC()
(SQL Server函数)的东西来检查值,但Postgresql(在我的例子中是DB2)似乎不存在这种功能。你最好创建一个UDF,你也可以给它一个默认值。哦,我不想更改功能-只需要为该类型定义一个默认值(例如,类似于cast('foo'为整数默认值-1)
之类的东西。只是想知道你是否可以澄清“注意双重类型转换以避免无限递归”?我本以为$1
已经是text/varchar
类型了。@Bruno:函数是cast\u to_int(text)
所以$1
将是text
,text
和varchar
是不同的类型。如果我们没有$1::varchar
的话,我们就要进行cast(文本为整数)
。但是这个cast是由cast\u to\u int
函数实现的,所以cast\u to\u int
最终会通过自定义cast间接调用自己。啊,这很有趣,我错误地认为text
和varchar
也会存在,但显然不会。AFAIKtext之间的唯一区别是什么e> 而varchar
就在PostgreSQL的边缘,一旦你通过了表面上的前两个分子,它们都是一样的。这里的人比我更了解内部细节。关于text
和varchar
之间的区别的一个问题,它引用了这一个,并将至少可能会被注意到。