I have a table with a column of data type LONG RAW
. How do I determine the size (in bytes) of the data in this column?
If I call the LENGTH
function on it, it raises ORA-00932: inconsistent datatypes: expected NUMBER got LONG BINARY
.
Just in case you think it: UTL_RAW.LENGTH
raises ORA-00997: illegal use of LONG datatype
:)
(Yes, I know LONG RAW
is deprecated - the question came up due to some old software that might require it)
You can use utl_raw. length on a PLSQL LONG RAW variable directly (since LONG RAW is synonym with RAW (32767) in PLSQL if I remember correctly).
LONG RAW is an Oracle data type for storing binary data of variable length up to 2 Gigabytes in length. Note that a table can only have one LONG RAW column.
LONG RAW data is like LONG data, except that LONG RAW data is not interpreted by PL/SQL. The maximum size of a LONG RAW value is 32760 bytes. You can insert any LONG value into a LONG database column because the maximum width of a LONG column is 2147483648 bytes or two gigabytes.
PL/SQL has two kinds of data types: scalar and composite. The scalar types are types that store single values such as number, Boolean, character, and datetime whereas the composite types are types that store multiple values, for example, record and collection.
I don't think it's possible to manipulate LONG RAWs longer than 32k in PLSQL. Here is a java procedure that returns the length of a LONG RAW.
First, the setup:
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
The java class (my java is a bit rusty):
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
Let's call it:
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
I've tested the function with larger than 32k fields and it seems to work.
As long as the data in the column does not exceed 16,383 bytes, you can solve this with a PL/SQL function, e.g.
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;
Unfortunately, a LONG RAW can hold up to 2GB...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With