We use Oracle 10g
and Oracle 11g
.
We also have a layer to automatically compose queries, from pseudo-SQL code written in .net (something like SqlAlchemy for Python).
Our layer currently wraps any string in single quotes '
and, if contains non-ANSI characters, it automatically compose the UNISTR
with special characters written as unicode bytes (like \00E0
).
Now we created a method for doing multiple inserts with the following construct:INSERT INTO ... (...)
SELECT ... FROM DUAL
UNION ALL SELECT ... FROM DUAL
...
This algorithm could compose queries where the same string field is sometimes passed as 'my simple string'
and sometimes wrapped as UNISTR('my string with special chars like \00E0')
.
The described condition causes a ORA-12704: character set mismatch
.
One solution is to use the INSERT ALL
construct but it is very slow compared to the one used now.
Another solution is to instruct our layer to put N
in front of any string (except for the ones already wrapped with UNISTR
). This is simple.
I just want to know if this could cause any side-effect on existing queries.
Note: all our fields on DB are either NCHAR
or NVARCHAR2
.
Oracle ref: http://docs.oracle.com/cd/B19306_01/server.102/b14225/ch7progrunicode.htm
What is the N+1 query problem The N+1 query problem happens when the data access framework executed N additional SQL statements to fetch the same data that could have been retrieved when executing the primary SQL query. The larger the value of N, the more queries will be executed, the larger the performance impact.
The error is caused due to complex Make Table Query which joins two local Access tables with a linked SQL Server table. The SQL server table has been increasing up its size dramatically so the query uses more temporary resources on the local PC. As, to process the query until it couldn’t bear anymore with 2 GB maximum limit reached.
The N+1 query problem is not specific to JPA and Hibernate, as you can face this issue even if you are using other data access technologies. The N+1 query problem happens when the data access framework executed N additional SQL statements to fetch the same data that could have been retrieved when executing the primary SQL query.
This particular Access Query Error occurs when you use aggregate functions in the query and you don’t set the Output All Fields property of the query to No. When you set the Output All Fields property of the query to Yes, a wildcard character (*) is get added to the select clause of the access query.
Basicly what you are asking is, is there a difference between how a string is stored with or without the N function.
You can just check for yourself consider:
SQL> create table test (val nvarchar2(20));
Table TEST created.
SQL> insert into test select n'test' from dual;
1 row inserted.
SQL> insert into test select 'test' from dual;
1 row inserted.
SQL> select dump(val) from test;
DUMP(VAL)
--------------------------------------------------------------------------------
Typ=1 Len=8: 0,116,0,101,0,115,0,116
Typ=1 Len=8: 0,116,0,101,0,115,0,116
As you can see identical so no side effect.
The reason this works so beautifully is because of the elegance of unicode
If you are interested here is a nice video explaining it
https://www.youtube.com/watch?v=MijmeoH9LT4
I assume that you get an error "ORA-12704: character set mismatch"
because your data inside quotes considered as char but your fields is nchar so char is collated using different charsets, one using NLS_CHARACTERSET
, the other NLS_NCHAR_CHARACTERSET
.
When you use an UNISTR
function, it converts data from char
to nchar
(in any case that also converts encoded values into characters) as the Oracle docs say:
"UNISTR takes as its argument a text literal or an expression that resolves to character data and returns it in the national character set."
When you convert values explicitly using N
or TO_NCHAR
you only get values in NLS_NCHAR_CHARACTERSET
without decoding. If you have some values encoded like this "\00E0"
they will not be decoded and will be considered unchanged.
So if you have an insert such as:
insert into select N'my string with special chars like \00E0',
UNISTR('my string with special chars like \00E0') from dual ....
your data in the first inserting field will be: 'my string with special chars like \00E0'
not 'my string with special chars like à'
. This is the only side effect I'm aware of. Other queries should already use NLS_NCHAR_CHARACTERSET encoding, so it shouldn't be any problem using an explicit conversion.
And by the way, why not just insert all values as N'my string with special chars like à'
? Just encode them into UTF-16 (I assume that you use UTF-16 for nchars) first if you use different encoding in 'upper level' software.
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