Oracle은 빈 문자열을 NULL로 간주하는 반면 SQL Server는 NULL로 간주하지 않습니다. 어떻게 하는 것이 가장 좋을까요?
Oracle 데이터베이스에 SQL Server 테이블(구조 및 데이터)을 다시 생성하는 구성 요소를 작성해야 합니다.또한 이 구성 요소는 오라클 데이터베이스에 입력된 새 데이터를 가져와 SQL 서버에 다시 복사해야 합니다.
SQL Server에서 Oracle로 데이터 유형을 변환하는 것은 문제가 되지 않습니다.큰 문제가 . 는 공백 을 Oracle SQL Server와 합니다. SQL Server는 빈 문자열("")을 다음과 다른 것으로 간주합니다.NULL
치가, 그서래.char
열은 다음과 같이 정의할 수 있습니다.NOT NULL
여전히 데이터에 빈 문자열을 포함합니다.
은 빈 을 Oracle과 합니다.NULL
만약 그, 만약서래값.char
열은 다음과 같이 정의됩니다.NOT NULL
빈 문자열을 삽입할 수 없습니다.이로 인해 구성 요소가 항상 손상됩니다.NOT NULL
데이터에 빈 문자열이 . char 열에원는 SQL Server 데이포함있다습니어.
지금까지 제 해결책은 사용하지 않는 것이었습니다.NOT NULL
더 강력한 솔루션이 필요합니다.이는 코드 솔루션이어야 하므로 "SQL2 Oracle 제품 사용"이 답이 될 수 없습니다.
이 문제를 어떻게 해결하시겠습니까?
편집: 여기 제가 지금까지 생각해 낸 유일한 해결책이 있습니다. 문제를 설명하는 데 도움이 될 수 있습니다.Oracle은 NOT NULL 열에 ""를 허용하지 않기 때문에 SQL Server에서 오는 모든 값을 가로채 "@"(예를 들어)로 바꿀 수 있습니다.
오라클 테이블에 새 레코드를 추가할 때, ""를 삽입하려면 코드가 "@"라고 써야 하고, 새 행을 SQL 서버에 다시 복사할 때 코드가 "@"를 가로채고 대신 ""라고 써야 합니다.
좀 더 우아한 방법이 있기를 바랍니다.
편집 2: 빈 문자열을 다른 모든 주요 데이터베이스와 동일하게 처리하도록 하는 오라클의 설정과 같은 더 간단한 솔루션이 있을 수 있습니까?또한 Oracle Lite에서도 이 설정을 사용할 수 있습니까?
저는 이것에 대한 쉬운 해결책을 보지 못합니다.
을 하나 의 빈칸으로 할 수 입니다.-> ' '
Oracle에서 NULLS가 아니거나 추가 필드/테이블 및 어댑터 계층을 통해 이 특수 사례를 추적합니다.
일반적인 솔루션은 SQL Server에 제약 조건을 추가하여 영향을 받는 열의 모든 문자열 값이 0보다 커지도록 하는 것입니다.
CREATE TABLE Example (StringColumn VARCHAR(10) NOT NULL)
ALTER TABLE Example
ADD CONSTRAINT CK_Example_StringColumn CHECK (LEN(StringColumn) > 0)
그러나 앞서 언급한 것처럼 SQL 데이터베이스를 제어할 수 없습니다.따라서 다음과 같은 네 가지 선택지가 있습니다(제가 보기에는).
- 빈 문자열 값을 잘못된 값으로 처리하고, 해당 레코드를 건너뛰고, 운영자에게 경고를 보내고, 수동으로 수정/재입력하기 쉬운 방법으로 레코드를 기록합니다.
- 빈 문자열 값을 공백으로 변환합니다.
- 빈 문자열 값을 코드(예: "LEGACY" 또는 "EMPTY")로 변환합니다.
- 이러한 열의 빈 문자열 값이 발생하는 전송을 롤백한 다음 SQL Server 데이터베이스 소유자에게 해당 데이터를 수정하도록 압력을 가합니다.
4번이 제 취향이겠지만, 항상 가능한 것은 아닙니다.Oracle 사용자가 필요로 하는 작업에 따라 수행하는 작업이 달라집니다.궁극적으로 SQL 데이터베이스에 대해 할 수 있는 일이 없다면 오라클 비즈니스 시스템 소유자에게 문제를 설명하고 옵션과 결과를 설명한 후 결정하도록 하겠습니다. :)
참고: 이 경우 SQL Server는 실제로 "올바른" 동작을 보여준다고 생각합니다.
SQL Server 시스템에서 빈 문자열을 허용해야 합니까?SQL Server 시스템에 빈 문자열을 허용하지 않는 제약 조건을 추가할 수 있다면 가장 쉬운 해결책일 것입니다.
그것은 끔찍하고 예상치 못한 부작용을 일으킬 수 있습니다.하지만 '가 아니라 'chr(0)'만 넣으면 됩니다.
drop table x
drop table x succeeded.
create table x ( id number, my_varchar varchar2(10))
create table succeeded.
insert into x values (1, chr(0))
1 rows inserted
insert into x values (2, null)
1 rows inserted
select id,length(my_varchar) from x
ID LENGTH(MY_VARCHAR)
---------------------- ----------------------
1 1
2
2 rows selected
select * from x where my_varchar is not null
ID MY_VARCHAR
---------------------- ----------
1
NOT NULL은 잘못된 데이터를 데이터베이스에 넣는 것을 중지하는 데 사용되는 데이터베이스 제약 조건입니다.이는 Oracle 데이터베이스에 아무런 용도가 없으므로 사용할 수 없습니다.
빈 문자열이 포함된 것으로 알려진 SqlServer 열을 미러링하는 모든 Oracle 열에서 NULLS를 계속 허용해야 합니다.
SqlServer 데이터베이스에서 NULL과 빈 문자열 사이에 논리적 차이가 있는 경우 Oracle에서 이 차이를 모델링하기 위해 추가적인 기능이 필요합니다.
오라클 쪽에 추가 열을 추가하고 싶습니다.열에서 null을 허용하고 SQL-Server 측이 행에 대해 null 값을 가져올지 빈 문자열을 가져올지 여부를 식별하는 두 번째 열이 있어야 합니다.
Null과 빈 문자열을 동일하게 간주해야 한다고 생각하는 사용자의 경우.null은 빈 문자열과 다른 의미를 가집니다.'정의되지 않음'과 '공백으로 알고 있음'의 차이를 캡처합니다.예를 들어 레코드가 자동으로 생성되었지만 사용자 입력에 의해 유효성이 확인되지 않았기 때문에 사용자가 레코드를 유효성 검사할 때 빈 레코드로 설정할 것으로 예상하여 'null'을 받습니다.실제로는 null에 대한 논리를 트리거하지 않고 빈 문자열에 대해 트리거할 수 있습니다.이는 예/아니오/정의되지 않음의 3 상태 확인란의 경우와 유사합니다.
SQL과 Oracle 모두 이를 완전히 정확하게 파악하지 못했습니다.공백은 'not null' 제약 조건을 충족하지 않아야 하며 빈 문자열은 null이 처리되는 것과 다르게 처리되어야 합니다.
데이터를 마이그레이션하는 경우 빈 문자열 대신 공백을 사용해야 할 수 있습니다.우아하지는 않지만, 작업할 수 있습니다.이것은 Oracle의 불쾌한 "기능"입니다.
얼마 전에 제 블로그에 오라클이 null 값을 처리하는 방법에 대한 설명을 작성했습니다.여기서 확인하세요: http://www.psinke.nl/blog/hello-world/ 그리고 더 궁금한 것이 있으면 저에게 알려주세요.값이 비어 있는 소스의 데이터가 있고 열이 NULL이 아닌 오라클 데이터베이스로 변환해야 하는 경우 다음 두 가지 방법을 수행할 수 있습니다.
- Oracle 열에서 null이 아닌 제약 조건 제거
- 데이터를 저장할 수 있도록 각 열에 ', 0 또는 더미 날짜를 입력할 수 있는지 여부를 확인합니다.
일부 필드가 null일 수 있고 동일한 필드가 빈 문자열일 수 있으며 비즈니스 로직에서 이러한 값을 구분해야 하는 경우에는 작업이 없다는 점을 고려해야 합니다.그래서 저는 다음과 같은 논리를 만들 것입니다.
- 열에 NULL 제약 조건이 없는 경우 MSSQL 확인
- 열에 CHECK(열 <> ') 또는 유사한 제약 조건이 있는 경우 MSSQL 확인
둘 다 참일 경우 Oracle 열을 NULL로 설정하지 마십시오.참인 경우 Oracle 열을 NULL로 만듭니다.참이 아닌 경우 잘못된 설계 예외를 제기합니다(또는 이 응용 프로그램에서 허용할 수 있는 경우 무시할 수도 있습니다).
MSSQL에서 Oracle로 데이터를 전송할 때는 특별한 작업을 수행하지 않으면 모든 데이터가 올바르게 전송됩니다.MSSQL로 데이터를 검색할 때 null이 아닌 모든 데이터를 그대로 전송해야 합니다.null 문자열의 경우 null로 삽입할지 빈 문자열로 삽입할지 결정해야 합니다.이렇게 하려면 테이블 설계를 다시 확인하고(또는 이전 결과를 기억) NULL 제약 조건이 없는지 확인해야 합니다.있으면 - 빈 문자열을 사용하고 없으면 - NULL을 사용합니다.단순하고 영리합니다.
알 수 없고 예측할 수 없는 애플리케이션으로 작업하는 경우 다양한 형식으로 인해 {not empty string} 제약 조건이 있는지 확인할 수 없는 경우가 있습니다.이 경우 단순화된 논리(Oracle 열을 항상 null로 함)를 사용하거나 MSSQL 테이블에 빈 문자열을 오류 없이 삽입할 수 있는지 여부를 확인할 수 있습니다.
비록, 대부분의 경우, 저는 대부분의 다른 반응에 동의합니다(제가 동의하지 않는 어떤 것에 대해서도 논쟁하지 않을 것입니다 - 그것을 위한 장소가 아닙니다:).
OP가 다음을 언급한 것을 알고 있습니다.
"Oracle은 빈 문자열을 NULL 값과 동일하게 간주하므로 char 열이 NOT NULL로 정의된 경우 빈 문자열을 삽입할 수 없습니다."
특히 VARCHAR2가 아닌 CHAR를 호출합니다.따라서 길이가 0인 "빈 문자열"(즉, ")에 대해 말하는 것은 무의미합니다.예를 들어, 그가 CHAR(5)로 선언한 다음 들어오는 빈 문자열에 공백을 추가하면 Oracle은 어쨌든 해당 문자열을 패딩합니다.당신은 결국 5개의 공백 문자열을 갖게 될 것입니다.
OP가 VARCHAR2를 의미한다면, 음, 그건 완전히 다른 짐승이고, 그래, 빈 문자열과 NULL의 차이는 관련이 있습니다.
SQL> drop table junk;
Table dropped.
SQL>
SQL> create table junk ( c1 char(5) not null );
Table created.
SQL>
SQL> insert into junk values ( 'hi' );
1 row created.
SQL>
SQL> insert into junk values ( ' ' );
1 row created.
SQL>
SQL> insert into junk values ( '' );
insert into junk values ( '' )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("GREGS"."JUNK"."C1")
SQL>
SQL> insert into junk values ( rpad('', 5, ' ') );
insert into junk values ( rpad('', 5, ' ') )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("GREGS"."JUNK"."C1")
SQL>
SQL> declare
2 lv_in varchar2(5) := '';
3 begin
4 insert into junk values ( rpad(lv_in||' ', 5) );
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>
언급URL : https://stackoverflow.com/questions/160904/oracle-considers-empty-strings-to-be-null-while-sql-server-does-not-how-is-thi
'programing' 카테고리의 다른 글
Git Revert 사용 방법 (0) | 2023.07.01 |
---|---|
Apache POI 데이터 포맷터가 과학적 표기법을 반환합니다. (0) | 2023.07.01 |
MongoDB - DBREF가 필요합니까? (0) | 2023.07.01 |
Vue.js 및 Vuex this.$store 반환을 새 Vue({store})에 추가한 후 정의되지 않음 (0) | 2023.07.01 |
어떻게 "참조" 값을 소방서에 삽입합니까? (0) | 2023.07.01 |