Как установить фиксированную длину для загрузки в столбец таблицы через загрузчик sql - PullRequest
0 голосов
/ 04 мая 2020

Итак, я хочу загрузить номер телефона через загрузчик sql, используя свой сценарий оболочки, потому что, когда я пытаюсь загрузить файл данных, содержащий 9 цифр, сценарий также загружает 9 строк di git. Я хочу, чтобы были загружены только 10 строк di git. Проблема в том, что я хочу, чтобы загрузчик sql принимал только строки, состоящие ровно из 10 цифр.

1 Ответ

2 голосов
/ 04 мая 2020

Насколько я могу судить, вы не можете; SQL* Загрузчик на это не способен. Предложение 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

Удалить то, что вы не делаете ' t want:

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>

Единственный недостаток этой опции в том, что у вас должен быть доступ в каталог, который (вообще говоря) расположен на сервере базы данных, поэтому вам придется поговорить со своим администратором баз данных.


Как видите, вариантов довольно много, но ни один из них не похож на вас ' d хочу.

...