Comments (4)
Hi,
I understand the issue.
Bujt you will get the same problem with all (at least 99%) Oracle OCI based libraries and even with the Java thin driver.
Even Sql*Plus cannot handle these situations, nor print these values.
If you were using the OCILIB C++ API, I would tell you to add you own template specialization for Statement::Bind() using a custom container
But apparently you are using the C API.
Maybe you could trick OCILIB by callingOCI_BindSetDataSize() with the "real size" beyond the null character.
I have to check if it could work. but even if it works for inserting, it will not work for selecting.
Instead of introducing a new type, i would rather try to find a way to give applications a way to indicate and retrieve the real length of a string bind/selected column row data.
If I can't find a good solution, I will think about adding a new type...
Best regards,
Vincent
from ocilib.
Technically it could be something like RAW datatype, but existing API does not allow us to reuse OCI_GetRaw() call over varchars.
Though I don’t have objection to have OCI_GetVarchar2 as near 1:1 copy of OCI_GetRaw, the same could be true for binds, why not?
from ocilib.
Hi,
Regarding your issue:
-binding in and out is not a problem
-gathering the real lenght on select can be addressed with a new function OCI_GetDataSize
unsigned int OCI_API OCI_GetDataSize
(
OCI_Resultset *rs,
unsigned int index
)
{
OCI_Define *def = NULL;
OCI_LIB_CALL_ENTER(unsigned int , 0)
OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs)
OCI_CHECK_BOUND(rs->stmt->con, index, 1, rs->nb_defs)
def = OCI_GetDefine(rs, index);
if (def && OCI_DefineIsDataNotNull(def))
{
ub2* lens = (ub2 *)def->buf.lens;
call_retval = lens[rs->row_cur - 1];
if (OCI_CDT_TEXT == def->col.datatype)
{
call_retval /= sizeof(otext);
}
}
OCI_LIB_CALL_EXIT()
}
Here is a complete sample code and its output:
int main()
{
OCI_Connection *cn;
OCI_Statement *st;
OCI_Resultset *rs;
otext buf[128] = "";
if (!OCI_Initialize(err_handler, NULL, OCI_ENV_DEFAULT))
return EXIT_FAILURE;
cn = OCI_ConnectionCreate("db12c", "usr", "pwd", OCI_SESSION_DEFAULT);
st = OCI_StatementCreate(cn);
OCI_ExecuteStmt(st, "SELECT value, LENGTH(VALUE), dump(VALUE) FROM (SELECT 'test' || chr(0) || 'me' VALUE FROM dual)");
rs = OCI_GetResultset(st);
while (OCI_FetchNext(rs))
{
printf("%s (size=%d) | %s (size=%d) | %s (size=%d)\n",
OCI_GetString(rs, 1), OCI_GetDataSize(rs, 1),
OCI_GetString(rs, 2), OCI_GetDataSize(rs, 2),
OCI_GetString(rs, 3), OCI_GetDataSize(rs, 3));
}
OCI_Prepare(st, "begin :1 := 'test' || chr(0) || 'me'; end;");
OCI_BindString(st, ":1", buf, sizeof(buf));
OCI_Execute(st);
printf("%s (size=%d), buf+5=%s\n", buf, OCI_BindGetDataSize(OCI_GetBind(st, 1)), buf + strlen(buf) + 1);
OCI_ExecuteStmt(st, "create table temp(value varchar2(50))");
OCI_ExecuteStmt(st, "insert into temp values( 'test' || chr(0) || 'me')");
OCI_ExecuteStmt(st, " select value from temp");
rs = OCI_GetResultset(st);
while (OCI_FetchNext(rs))
{
char *s = OCI_GetString(rs, 1);
printf("%s (size=%d), buf+5=%s\n", s, OCI_GetDataSize(rs, 1), s + strlen(s) + 1);
}
OCI_ExecuteStmt(st, "drop table temp");
OCI_Cleanup();
return EXIT_SUCCESS;
}
Output:
test (size=7) | 7 (size=2) | Typ=1 Len=7: 116,101,115,116,0,109,101 (size=38)
test (size=7), buf+5=me
test (size=7), buf+5=me
Is that sounds okay for you ?
from ocilib.
OCI_GetDataSize() - it's a brilliant solution, I much satisfied, thank you.
Separate OCI_Varchar2 datatype could be unreasonably complex solution, indeed.
So simple function call fully resolves our case. I also tested Direct Path API - it handles the 0x0 char in the middle of the string properly.
Please close the issue.
from ocilib.
Related Issues (20)
- OCI_RefToText() return garbage when charset is OCI_CHARSET_WIDE HOT 1
- Error occurred at OcilibEnvironmentInitialize: Cannot load OCI shared library (oci.dll) HOT 4
- Error occurred at OcilibResultsetFetchFirst: A null Resultset handle has been provided HOT 5
- Regarding the use of connection pool to obtain links, will it be automatically recycled by connection pool? HOT 1
- I don't know why I suddenly reported this error: ocilib\include\ocilibcpp\detail\exception.hpp(92): error C2061: syntax error: identifier 'nothrow' HOT 1
- Regarding using ocilib::Pool to get links ,what happens if the maximum link is reached? HOT 1
- symbol not found in flat namespace '_OCIAQDeq' (macOS arm64) HOT 3
- Wrapper for OCINlsGetInfo() HOT 1
- On connection pool problem HOT 6
- On the limitation of the number of preprocessing bindings? HOT 1
- Why does ocilib::Resultset restrict the default construct? HOT 1
- crash with using change notification HOT 1
- Free memory after dequeue HOT 1
- DCN getObjectName display mess code HOT 1
- Invalid problem of batch std::vector<ocilib::Date > date display. HOT 4
- C++ Value types perform handle assignment instead of value assignment
- Two doubts ! HOT 1
- Reusing prepared statement hangs HOT 2
- OcilibElementSetRaw bug HOT 1
- Pool connection is never released (C++) HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ocilib.