Oracle (50)

이 오류는 Blob형태의 데이타를 String변수에 받아오려고 할때 발생한다.

Blob형태의 데이타를 받아올때는 String변수 대신에 byte[]를 써야한다.


💻 Programming/Oracle 11g

ORA-00917: 누락된 콤마

말그대로 콤마가 누락되었다는 얘기다.  

하지만!!!!! 때로는 엉뚱한 실수에 엉뚱한 오류가 나기도 한다.

 

내가 저 에러메시지를 본것은 아래와 같은 설정을 했을때다.

스프링 기반 웹앱을 만들고 xml파일에 쿼리문을 넣었는데....

 

================================================ 

<insert id="add">
        insert into
            테이블명
        values(
            column1 = #{col1, jdbcType=VARCHAR}
            ,​column2 = #{col2, jdbcType=VARCHAR}
            ,​column3 = #{col3, jdbcType=VARCHAR}
        )
</insert> 

================================================

자, 여기서 테이블명과 컬럼명은 임의로 써넣었다. 물론 실제 소스에서는 실제 테이블명과 컬럼명이 들어가있다. 이 테이블에는 세개의 컬럼( column1, column2, column3 )이 있다고 가정한다. 

 

이 코드에서 왜 누락된 콤마 누락 에러가 발생했는지 찾았는가???

 

이 코드에는 콤마가 누락된 것이 아니다. Insert 문의 형식자체가 틀렸다.

위 코드는 아래와 같이 바뀌어야 한다.

 

        insert into
            테이블명
        values(
            #{col1, jdbcType=VARCHAR}
            ,​#{col2, jdbcType=VARCHAR}
            ,​#{col3, jdbcType=VARCHAR}
        ) 

 

에러메시지만보고 콤마가 어디가 누락됐다는거지? 라는 생각을 가지고 오류를 찾으려한다면 하루종일을 허비해도 못찾을 것이다.

 

당신의 지식에 조금이나마 도움이 됐기를 바라며 글을 마친다.... 


아래 예제는 JMNote.com의 위키페이지에서 복사해온 것임을 밝힙니다.

( 원본 주소 - 

http://jmnote.com/wiki/%EC%98%A4%EB%9D%BC%ED%81%B4_%EC%BB%AC%EB%9F%BC%EB%AA%85_%EC%88%9C%EC%84%9C_%EB%B3%80%EA%B2%BD

실습 테이블 생성

CREATE TABLE employee (
emp_no NUMBER PRIMARY KEY,
dept VARCHAR2 (16),
name VARCHAR2 (32)
);
INSERT INTO employee VALUES (130001, '인사부', '홍길동');
INSERT INTO employee VALUES (130002, '영업부', '임꺽정');
INSERT INTO employee VALUES (130003, '생산부', '장길산');

변경 전

SELECT * FROM employee;
EMP_NO  DEPT    NAME
130001  인사부       홍길동
130002  영업부       임꺽정
130003  생산부       장길산

변경

  • 재배열된 사본 생성 → 사본을 원본으로 대체
CREATE TABLE temp AS SELECT emp_no, name, dept FROM employee;
DROP TABLE employee;
RENAME temp TO employee;

변경 후

SELECT * FROM employee;
EMP_NO  NAME    DEPT
130001  홍길동       인사부
130002  임꺽정       영업부
130003  장길산       생산부


오라클에서 테이블에 새로운 PRIMARY KEY를 추가하고 이를 FK로 만들어주고 싶었다.

그러다가 그만 ORA-02270 에러를 만나게 되었다.

만나게 된 상황은 이렇다.

 

테이블 A와 B가 있다.

테이블 A는 a라는 PK가 있고 테이블 B는 (a, b)를 복합PK로 가지고 있었다.

자, 여기서 A와 B테이블에 컬럼c를 추가하고 복합PK로 만들어주려했다.

즉, A의 PK는 (a, c), 그리고 B의 PK는 (a, b, c)가 되는것이다. 그리고 B의 a, c는 FK로 A의 a, c를 참조해야한다.

 

이를 하기위해서 생각했던 순서는 아래와 같다. 

 

1. 테이블 A, B의 PK를 DROP한다.

2. 테이블 A, B에 컬럼c를 추가한다.

3. 테이블 A의 PK로 (a, c)를 선언한다. 

3. 테이블 B의 a를 FK로 선언하면서 A의 a를 참조하도록 한다.

 - alter table B add foreign key (a) references A(a);

4. 테이블 B의 c를 FK로 선언하면서 A의 c를 참조하도록 한다.

 - alter table B add foreign key (c) references A(c);

5. 테이블 B의 PK로 (a, b, c)를 선언한다.

 

하지만 3번에서 02270 에러를 만나게 되었다.

이 에러는 UNIQUE KEY나 PK가 아닌것을 참조하려고 했기 때문에 발생하는 에러이다.

그래서 생각해보니 테이블 A의 PK는 a나 c가 아닌 (a, c)인 것이다.

하여 3, 4번 과정을 묶어서 테이블 B의 FK로 B의 (a, c)가 A의 (a, c)를 참조하도록 설정하였더니 문제가 해결되었다.

 - alter table B add foreign key (a, c) references A(a, c);


💻 Programming/Oracle 11g

[SQL] Truncate vs Drop vs Delete

DELETE

The DELETE command is used to remove rows from a table. A WHERE clause can be used to only remove some rows. If no WHERE condition is specified, all rows will be removed. After performing a DELETE operation you need to COMMIT or ROLLBACK the transaction to make the change permanent or to undo it. Note that this operation will cause all DELETE triggers on the table to fire.

 

TRUNCATE

TRUNCATE removes all rows from a table. The operation cannot be rolled back and no triggers will be fired. As such, TRUCATE is faster and doesn't use as much undo space as a DELETE.

 

DROP

The DROP command removes a table from the database. All the tables' rows, indexes and privileges will also be removed. No DML triggers will be fired. The operation cannot be rolled back.  

 

 

* DROP and TRUNCATE are DDL commands, whereas DELETE is a DML command. Therefore DELETE operations can be rolled back (undone), while DROP and TRUNCATE operations cannot be rolled back.


오라클에서 한번에 여러개의 레코드를 insert하려면 아래와 같은 방식을 사용할 수 있다.

 

 

INSERT ALL
INTO 테이블명 ( column_1, column_2 ) VALUES ( value_1,  value_2)

INTO 테이블명 ( column_1, column_2 ) VALUES ( value_3,  value_4)

SELECT 1 FROM DUAL


💻 Programming/Oracle 11g

[SQL] COUNT(*) 와 COUNT(1)

SQL에서 특정 데이타의 개수를 뽑아낼 때 사용하는 COUNT()함수가 있다.

뭐 데이터의 양이 적은 경우에는 속도차이를 느끼지 못하겠지만 데이터의 양이 많은 DB를 사용하는 경우에는 어떨까...????하는 의문이 생긴다.

 

아직 확실한 테스트를 해보지는 않았다. 그저 인터넷에서 찾은 정보에 의하면....

 

영어에 약한분들은 Example부분은 그냥 건너뛰고 Tip: Performance......부분을 보면된다. 

================================================================= 

Example - Using SQL GROUP BY Clause

In some cases, you will be required to use the SQL GROUP BY clause with the SQL COUNT function.

For example, you could use the SQL COUNT function to return the name of the department and the number of employees (in the associated department) that make over $25,000 / year.

SELECT department, COUNT(*) AS "Number of employees"
FROM employees
WHERE salary > 25000
GROUP BY department;

Because you have listed one column in your SQL SELECT statement that is not encapsulated in the SQL COUNT function, you must use the SQL GROUP BY clause. The department field must, therefore, be listed in the GROUP BY section.

TIP: Performance Tuning with SQL COUNT

Since the SQL COUNT function will return the same results regardless of what NOT NULL field(s) you include as the SQL COUNT function parameters (ie: within the brackets), you can change the syntax of the SQL COUNT function to COUNT(1) to get better performance as the database engine will not have to fetch back the data fields.

For example, based on the example above, the following syntax would result in better performance:

SELECT department, COUNT(1) AS "Number of employees"
FROM employees
WHERE salary > 25000
GROUP BY department;

Now, the SQL COUNT function does not need to retrieve all fields from the employees table as it had to when you used the COUNT(*) syntax. It will merely retrieve the numeric value of 1 for each record that meets your criteria.

======================================================================== 

 

 

 

출처 :Http://www.techonthenet.com/sql/count.php


java.lang.SecurityException: Sealing violation exception (ID 6554602)

Description

Starting with JDBC 10.2 drivers, having more than one JDBC jar file in the CLASSPATH may result in a java.lang.SecurityException: Sealing violation exception.

Detailed explanation from Oracle is documented in the following Oracle Document ID:

Note:405446.1
Subject: JDBC Driver 10.2 Uses Sealed JAR files and May Cause SecurityException Sealing Violation

Solution

(Suggested by Oracle) Make sure that the CLASSPATH includes only one JDBC driver JAR file.

=============================================================================


💻 Programming/Oracle 11g

[SQL] CONNECT BY , START WITH

계층 구조를 가진 데이타를 뽑아보자!!!!

한 테이블 Table_1이 있다.

이 테이블은 objectID필드와 parentObjectID 필드를 갖고 있다.

두 필드에는 OBJECT_X(X는 정수형 숫자)형식의 데이터가 들어있다. 

또, OBJECT_1이 하위 OBJECT_2를 가지고 OBJECT_2가 또 하위 OBJECT_3을 가진다고 가정하자. (OBJECT_2는 OBJECT_1의 자식 OBJECT라고 생각하면된다.)

여러 다른 OBJECT_X 형식의 데이터들이 테이블 내에 많이 있다고 가정하자.

 

이때 CONNECT BY와 START WITH를 이용하여 OBJECT_2와 그 상위, 또 그 상위, 또 그 상위...쭈우욱 해서 OBJECT_2를 갖는 최상위 OBJECT까지 계층구조로 뽑아내기 위해서는 아래와 같이 하면 된다.

 

SELECT *

FROM Table_1

CONNECT BY PRIOR objectID = parentObjectID

START WITH objectID = 'OBJECT_2'

 

------- 

 파란색 조건부의 순서가 바뀌면 결과도 바뀌므로 주의하자.!!!!


테이블 백업을 할때에 export / import 를 이용할 수도 있지만 단순하게 rename 명령어를 이용할 수도 있습니다. 또한 create ~ as select ~ 를 이용할 수도 있습니다.

하지만 오늘은 테이블 명을 변경하고 새로 테이블을 생성함으로써 백업을 할 수 있는 방법을 소개하도록 하겠습니다. 참고로 이 방법은 blob데이타가 많은 경우에 상당히 유용합니다.


Step by Step

1) Query table name and index names linked to the table you want to backup

2) Rename table name

3) Rename indexes' name ( if specified explicitly when it is created )

4) Rename constraints' name ( if specified explicitly when it is created )

4) Use the same DDL used to create the renamed table


※ This way is very simple and fast then using "create table ~ as select * from ~" statement when the table has a huge blob data.



1) 변경하고자하는 테이블에 어떤 인덱스들이 있는지 조회합니다.

SQL > select index_name, table_name from user_indexes;


2) 테이블명을 변경합니다.

SQL > rename old_table to new_table;


3) 인덱스명을 변경합니다. ( 인덱스명이 자동생성된 것이 아닌 경우에만 )

SQL > alter index pk_old_table rename to pk_new_table;


4) 제약사항명을 변경합니다. ( 제약사항명이 자동생성된 것이 아닌 경우에만 )

SQL > select * from user_cons_columns where table_name='{table_name};

SQL > alter table {table name} rename constraint {constraint name} to {new constraint name}


5) 기존 테이블을 생성했던 DDL을 사용하여 테이블을 새로 생성합니다.

SQL > create table .........