ПОЛУЧИТЕ ДЛИНУ ДЛИННОГО СЫРЬЯ
У меня есть таблица со столбцом типа данных LONG RAW
, Как определить размер (в байтах) данных в этом столбце?
Если я позвоню LENGTH
функция на это, это повышает ORA-00932: inconsistent datatypes: expected NUMBER got LONG BINARY
,
На всякий случай, если вы думаете, это: UTL_RAW.LENGTH
повышения ORA-00997: illegal use of LONG datatype
:)
(Да, я знаю LONG RAW
устарел - вопрос возник из-за какого-то старого программного обеспечения, которое может потребоваться)
3 ответа
Я не думаю, что в PLSQL можно манипулировать LONG RAW длиннее 32k. Вот процедура Java, которая возвращает длину LONG RAW.
Во-первых, настройка:
SQL> CREATE TABLE my_table (ID NUMBER, my_long_raw_column LONG RAW);
Table created
SQL> INSERT INTO my_table VALUES (1, utl_raw.cast_to_raw('123456789'));
1 row inserted
Класс Java (мой Java немного ржавый):
SQL> CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Raw" AS
2 import java.io.*;
3 import java.sql.*;
4 import oracle.jdbc.driver.*;
5
6 public class Raw {
7
8 public static int getLength(int pk) throws SQLException,IOException {
9
10 Connection conn = new OracleDriver().defaultConnection();
11
12 PreparedStatement ps = conn.prepareStatement
13 ( "SELECT my_long_raw_column FROM my_table WHERE id = ?" );
14 ps.setInt( 1, pk);
15 ResultSet rs = ps.executeQuery();
16
17 int len = 0;
18 if (rs.next()) {
19 InputStream is = rs.getBinaryStream(1);
20 int nb = is.read(new byte[1024]);
21 while (nb>0) {
22 len += nb;
23 nb = is.read(new byte[1024]);
24 }
25 } else
26 len = -1;
27
28 rs.close();
29 ps.close();
30
31 return len;
32 }
33 }
34 /
Java created
Давайте назовем это:
SQL> CREATE OR REPLACE
2 FUNCTION get_lr_length(p_id NUMBER) RETURN NUMBER
3 AS LANGUAGE JAVA
4 NAME 'Raw.getLength(int) return int';
5 /
Function created
SQL> select get_lr_length(id) from my_table;
GET_LR_LENGTH(ID)
-----------------
9
Я протестировал функцию с полями размером более 32 Кб, и она, кажется, работает.
Пока данные в столбце не превышают 16 383 байта, это можно решить с помощью функции PL/SQL, например:
CREATE OR REPLACE FUNCTION get_lr_length (id IN NUMBER)
RETURN NUMBER IS
raw_data LONG RAW;
hex_data VARCHAR2(32767);
len NUMBER;
BEGIN
SELECT my_long_raw_column INTO raw_data
FROM my_table
WHERE my_table.id = get_lr_length.id;
hex_data := RAWTOHEX(raw_data);
len := LENGTH(hex_data) / 2;
RETURN len;
END get_lr_length;
К сожалению, LONG RAW может вместить до 2 ГБ...
Один подвох, который может помочь, если вы играете с небольшой тестовой базой данных: скопируйте все данные в таблице с помощью BLOB
вместо LONG RAW
,
create table START(ID int not null, VAL long raw);
... inserts
create table START_BLOB(ID int not null, VAL blob);
insert into START_BLOB(ID,VAL) select ID,to_lob(VAL) from STAR;
select ID,length(VAL) from START_BLOB;