oracle - 如何通过 sql loader 设置要加载到表列中的固定长度
问题描述
因此,我想使用我的 shell 脚本通过 sql loader 加载电话号码,因为当我尝试加载包含 9 位数字的数据文件时,脚本也会加载 9 位数字行。我只希望加载 10 位数的行。问题是我希望将 sql 加载器设置为仅接受正好 10 位数字的行。
解决方案
据我所知,你不能;SQL*Loader 无法做到这一点。WHEN
子句会非常好,只要它接受像length
. 但是,事实并非如此。
我能想到的最简单的选择是全部加载它们,然后删除不需要的行。例如:
表说明:
SQL> desc test
Name Null? Type
----------------------------------------- -------- ----------------------
TEL VARCHAR2(10)
SQL> select * From test;
no rows selected
控制文件:
load data
infile *
replace
into table test
(
tel char(10)
)
begindata
1234567890
986532554
3216549878
21212
运行:
SQL> $sqlldr scott/tiger control=test19.ctl log=test19.log
SQL*Loader: Release 11.2.0.2.0 - Production on Pon Svi 4 21:46:17 2020
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 4
SQL> select * From test;
TEL
----------
1234567890
986532554
3216549878
21212
删除你不想要的:
SQL> delete from test where length(tel) < 10;
2 rows deleted.
SQL> select * From test;
TEL
----------
1234567890
3216549878
SQL>
另一个会默默跳过不需要的值的选项是数据库触发器。为了做到这一点,创建一个基于表的视图和一个代替触发器:
SQL> truncate table test;
Table truncated.
SQL> create or replace view v_test as select * From test;
View created.
SQL> create or replace trigger trg_bivt
2 instead of insert on v_test
3 for each row
4 begin
5 if length(:new.tel) < 10 then
6 null;
7 else
8 insert into test (tel) values (:new.tel);
9 end if;
10 end;
11 /
Trigger created.
让我们尝试一下:
SQL> $sqlldr scott/tiger control=test19.ctl log=test19.log
SQL*Loader: Release 11.2.0.2.0 - Production on Pon Svi 4 21:52:59 2020
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 4
SQL> select * From test;
TEL
----------
1234567890
3216549878
SQL>
这个选项很好,但是当您加载大量数据时性能会受到影响。
另一种选择是外部表。它的好处是可以将源文件视为普通的 Oracle 表——您可以直接针对它编写查询。为了使用它,创建一个目录并向将使用它的用户授予权限:
SQL> show user
USER is "SYS"
SQL> create directory ext_dir as 'c:\temp';
Directory created.
SQL> grant read, write on directory ext_dir to scott;
Grant succeeded.
SQL>
创建外部表:
SQL> show user
USER is "SCOTT"
SQL> create table test_ext
2 (tel varchar2(10))
3 organization external
4 (type oracle_loader
5 default directory ext_dir
6 access parameters (records delimited by newline
7 fields terminated by ','
8 (tel char(10))
9 )
10 location ('test.txt')
11 )
12 reject limit unlimited;
Table created.
SQL>
Test.txt 内容:
1234567890
986532554
3216549878
21212
它有效吗?
SQL> select * From test_ext;
TEL
----------
1234567890
986532554
3216549878
21212
SQL>
现在,只插入您想要接受的行:
SQL> truncate table test;
Table truncated.
SQL> insert into test (tel)
2 select tel
3 from test_ext
4 where length(tel) = 10;
2 rows created.
SQL> select * from test;
TEL
----------
1234567890
3216549878
SQL>
此选项的唯一缺点是您必须有权访问(一般而言)位于数据库服务器上的目录,因此您必须与您的 DBA 交谈。
如您所见,有很多选择,但没有一个完全符合您的要求。
推荐阅读
- python - numpy - 给定二维矩阵的按列和按行求和
- python - 如何将大型数据集拆分为块并执行 fit_transform / fit_resample 和联合结果?
- python - 我在训练我的 GAN 时遇到值错误,例如:“ValueError: Target size (torch.Size([10, 1])) must be the same as input size (torch.Size([10]))”
- c - 以下 C 代码输出分段错误错误,我几乎无法理解为什么
- java - 一个对象可以保存一个由它自己的对象组成的数组。但是这如何与继承一起工作呢?
- ios - 更改暗模式时未更新 HTML 字符串中的颜色
- amazon-web-services - 无服务器框架部署错误:您无权访问此资源
- php - 将mysql值转换为列
- python - 在 PyTorch 中将 5D 张量转换为 4D 张量
- wpf - 是否可以在需要时使用 get in property 创建命令的新实例?