Oracle 希望我使用 Long 而不是 CLOB
Oracle wants me to use a Long instead of a CLOB
TLDR:Oracle 说我只能绑定一个 LONG 值以插入到一个 LONG 列中...但是该列是一个 CLOB,我相信它应该能够处理这个大小的值。
我有一个带有 CLOB 列的 table:
CREATE TABLE "WEB"."DATA_EXPLORER_QUERIES"
( "ID" NUMBER NOT NULL ENABLE,
"USER_ID" NUMBER NOT NULL ENABLE,
"CREATE_DATE" DATE NOT NULL ENABLE,
"LAST_RUN" DATE DEFAULT sysdate NOT NULL ENABLE,
"RUNS" NUMBER(*,0) DEFAULT 1 NOT NULL ENABLE,
"TITLE" VARCHAR2(2500 BYTE) NOT NULL ENABLE,
"SLUG" VARCHAR2(2500 BYTE) NOT NULL ENABLE,
"SQL" CLOB NOT NULL ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS NOLOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
LOB ("SQL") STORE AS SECUREFILE (
TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192
NOCACHE NOLOGGING NOCOMPRESS KEEP_DUPLICATES
STORAGE(INITIAL 106496 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)) ;
我正在尝试通过 PHP:
插入一些数据
$q = $pdo_internal->prepare("insert into data_explorer_queries (id, user_id, create_date, last_run, runs, title, slug, sql) values (?, ?, sysdate, sysdate, 1, ?, ?, ?)");
$q->execute([
$id,
$_SESSION['user_id'],
$_POST['title'],
$modified_slug,
$_POST['sql']
]);
这里有一个var_dump
的数据:
array (size=5)
0 => string '5' (length=1)
1 => string '1078' (length=4)
2 => string 'test' (length=4)
3 => string 'test' (length=4)
4 => string 'select
ziplist.n,
sz.zip,
round((nvl(sz.home_count,0) + nvl(sz.apt_count,0)) * .01515) as census_average
from standard_zip sz
inner join (
select 1 as n, 59421 as zip from dual
union all select 2 as n, 83213 as zip from dual
union all select 3 as n, 59201 as zip from dual
union all select 4 as n, 89001 as zip from dual
union all select 5 as n, 59410 as zip from dual
union all select 6 as n, 83128 as zip from dual
union all select 7 as n, 59937 as zip from dual
union all select 8 as n, 84021 as '... (length=22066)
这将引发以下异常:
PDOException: SQLSTATE[HY000]: General error: 1461 OCIStmtExecute: ORA-01461: can bind a LONG value only for insert into a LONG column
有趣的是,当我打开 SQLDeveloper 并双击 table 中 CLOB 列中的任何值时,我能够粘贴这个长字符串并通过 UI 保存它。显然这只是使用 PHP/PDO.
时的问题
我做错了什么?我该如何解决这个问题?
在我将其标记为重复之前,为了方便起见,我会在这里留下一个答案。 (归功于 )
Per , PHP Bug #57095 表示在将参数传递给 execute
方法时,插入 CLOB 值无法按预期工作。
解决方法是使用 bindParam
并将 CLOB 类型指定为字符串,并包括第 4 个参数以指示 CLOB 值的字符串大小。
我更新后的工作代码:
$q = $pdo_internal->prepare("insert into data_explorer_queries (id, user_id, create_date, last_run, runs, title, slug, sql) values (?, ?, sysdate, sysdate, 1, ?, ?, ?)");
$q->bindParam(1, $id, PDO::PARAM_INT);
$q->bindParam(2, $_SESSION['user_id'], PDO::PARAM_INT);
$q->bindParam(3, $_POST['title']);
$q->bindParam(4, $modified_slug);
$q->bindParam(5, $_POST['sql'], PDO::PARAM_STR, strlen($_POST['sql']));
$q->execute();
TLDR:Oracle 说我只能绑定一个 LONG 值以插入到一个 LONG 列中...但是该列是一个 CLOB,我相信它应该能够处理这个大小的值。
我有一个带有 CLOB 列的 table:
CREATE TABLE "WEB"."DATA_EXPLORER_QUERIES"
( "ID" NUMBER NOT NULL ENABLE,
"USER_ID" NUMBER NOT NULL ENABLE,
"CREATE_DATE" DATE NOT NULL ENABLE,
"LAST_RUN" DATE DEFAULT sysdate NOT NULL ENABLE,
"RUNS" NUMBER(*,0) DEFAULT 1 NOT NULL ENABLE,
"TITLE" VARCHAR2(2500 BYTE) NOT NULL ENABLE,
"SLUG" VARCHAR2(2500 BYTE) NOT NULL ENABLE,
"SQL" CLOB NOT NULL ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS NOLOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
LOB ("SQL") STORE AS SECUREFILE (
TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192
NOCACHE NOLOGGING NOCOMPRESS KEEP_DUPLICATES
STORAGE(INITIAL 106496 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)) ;
我正在尝试通过 PHP:
插入一些数据$q = $pdo_internal->prepare("insert into data_explorer_queries (id, user_id, create_date, last_run, runs, title, slug, sql) values (?, ?, sysdate, sysdate, 1, ?, ?, ?)");
$q->execute([
$id,
$_SESSION['user_id'],
$_POST['title'],
$modified_slug,
$_POST['sql']
]);
这里有一个var_dump
的数据:
array (size=5)
0 => string '5' (length=1)
1 => string '1078' (length=4)
2 => string 'test' (length=4)
3 => string 'test' (length=4)
4 => string 'select
ziplist.n,
sz.zip,
round((nvl(sz.home_count,0) + nvl(sz.apt_count,0)) * .01515) as census_average
from standard_zip sz
inner join (
select 1 as n, 59421 as zip from dual
union all select 2 as n, 83213 as zip from dual
union all select 3 as n, 59201 as zip from dual
union all select 4 as n, 89001 as zip from dual
union all select 5 as n, 59410 as zip from dual
union all select 6 as n, 83128 as zip from dual
union all select 7 as n, 59937 as zip from dual
union all select 8 as n, 84021 as '... (length=22066)
这将引发以下异常:
PDOException: SQLSTATE[HY000]: General error: 1461 OCIStmtExecute: ORA-01461: can bind a LONG value only for insert into a LONG column
有趣的是,当我打开 SQLDeveloper 并双击 table 中 CLOB 列中的任何值时,我能够粘贴这个长字符串并通过 UI 保存它。显然这只是使用 PHP/PDO.
时的问题我做错了什么?我该如何解决这个问题?
在我将其标记为重复之前,为了方便起见,我会在这里留下一个答案。 (归功于
Per execute
方法时,插入 CLOB 值无法按预期工作。
解决方法是使用 bindParam
并将 CLOB 类型指定为字符串,并包括第 4 个参数以指示 CLOB 值的字符串大小。
我更新后的工作代码:
$q = $pdo_internal->prepare("insert into data_explorer_queries (id, user_id, create_date, last_run, runs, title, slug, sql) values (?, ?, sysdate, sysdate, 1, ?, ?, ?)");
$q->bindParam(1, $id, PDO::PARAM_INT);
$q->bindParam(2, $_SESSION['user_id'], PDO::PARAM_INT);
$q->bindParam(3, $_POST['title']);
$q->bindParam(4, $modified_slug);
$q->bindParam(5, $_POST['sql'], PDO::PARAM_STR, strlen($_POST['sql']));
$q->execute();