是否可以创建一个自动将SQL值从日期转换为字符串的函数?
例如使用以下查询:
SELECT first_name, last_name, TO_CHAR(birthday, 'MM/DD/YYYY') as birthday FROM master
有什么方法可以放弃 TO_CHAR 声明并让数据库为我自动转换值吗?我一直试图找到一个动态解决方案,以便它自动转换每个表中 DATE 列中的任何值,但无济于事。
理想情况下,我只想运行以下查询:
SELECT first_name, last_name, birthday FROM master
以所需格式获取所有值。是否也可以反之亦然:
INSERT INTO master (first_name, last_name, birthday)
VALUES (:first_name, :last_name, TO_DATE(:birthday, 'MM/DD/YYYY'))
到:
INSERT INTO master (first_name, last_name, birthday)
VALUES (:first_name, :last_name, :birthday)
回答
如果您以日期开头,但 Oracle 需要将其作为字符串(例如用于显示输出!),您可以使用TO_CHAR, 带或不带格式模型(以及一些其他需要的参数),或者不使用任何东西并且OracleTO_CHAR会隐式地调用您,并为参数提供默认值。当然,最重要的是日期格式模型。这是一个名为nls_date_format;的会话参数。要查看所有nls 设置,您可以运行
select * from v$nls_parameters;
相反,如果您以字符串开头但 Oracle 需要日期(例如,插入日期数据类型的列中,或用于某些日期计算等),则可以使用TO_DATE、带或不带日期格式模型,或 Oracle 为您调用它 - 再次使用默认值,包括nls_date_format.
请注意,某些(但不是全部)前端会忽略您nls_date_format并使用您在用户界面中找到的设置。如果你问我,那是愚蠢的功能,但你只需要知道它。
另请注意,timestamp和date是不同的,并且它们使用不同的nls参数进行默认格式设置。与timestamp with time zone. 因此,如果某些事情看起来不对,请仔细考虑数据类型。
在我的系统上:
select value from v$nls_parameters where parameter = 'NLS_DATE_FORMAT';
VALUE
----------------------------------------------------------------
dd-MON-yyyy
select sysdate from dual; -- I didn't use `to_char` so Oracle did
SYSDATE
-----------
12-MAR-2021
create table t (dt date);
insert into t (dt) values ('12-OCT-2020'); -- BAD PRACTICE!
select * from t;
DT
-----------
12-OCT-2020
现在,请注意隐式转换团队会追捕滥用隐式转换的开发人员。既然您知道它是如何完成的,就不要在任何重要的地方(例如在生产中)这样做。在开发查询时快速构建测试用例是可以的;一般而言,实践非常糟糕。根据需要使用TO_CHAR和TO_DATE,你会没事的!
- See also: [Oracle's default DATE format](https://stackoverflow.com/a/50164234/1509264). The default varies depending on which territory is set on your database; so you should **NEVER** rely on implicit conversions when you are working in an international setting as users in different countries are likely to have different default `NLS_DATE_FORMAT` values.