JDBC getNString() - sql-server

I'm working with a Java web application backed by a Microsoft SQL Server. I have used nvarchar columns and my plan is to support Unicode characters. So in my JDBC layer I have used getNString() method from the result set and it works fine. However just for curiosity I changed all the getNString() methods to normal getString() methods and it also works fine displaying Unicode characters correctly.
I found the similar observation from below question as well
Should I be using JDBC getNString() instead of getString()?
Do you guys have any idea about this?

The presence of getNString and setNString is - in my opinion - a design mistake of JDBC. However, database systems that discern between (VAR)CHAR and N(VAR)CHAR can take this setter as a type hint to send the data in their specific format for N(VAR)CHAR. For getters there will usually be no difference as in most drivers, the data will have already been fetched before this method can be called, and a driver should know the proper conversion.
Specifically for the Microsoft SQL Server JDBC driver, with default configuration there is no difference between using setString or setNString: both will lead to the values being sent as unicode. This changes when the connection property sendStringParametersAsUnicode has been set to false.
See also NVARCHAR Support in Type 2 SQL Server 2008 JDBC Driver:
You do not need to use the JDBC 4 API to work with NVARCHAR (UCS-2)
data in SQL Server. Existing JDBC 3 APIs such as
getString/setString/updateString are used to get/set/update Unicode
values as Java Strings (which are always Unicode). The only thing to
be aware of when using the JDBC 3 methods is the setting of the
sendStringParametersAsUnicode property. This property is set to
'true' by default, which means that PreparedStatement and
CallableStatement parameters are sent to SQL Server in Unicode.
Changing the setting to 'false' allows the driver to save space in the
protocol by converting input parameter values to the character set of
the database when sending them.
That said, using the JDBC 4 API to work with NVARCHAR data has some
advantages. The main advantage is formal recognition of the NVARCHAR
type by the JDBC API, including accessor methods such as
getNString/setNString/updateNString. For example, the setNString
method can be used to send input parameter values to SQL Server in
Unicode, even if sendStringParametersAsUnicode is set to 'false'.
Put another way, with the default setting of
sendStringParametersAsUnicode=true, the JDBC 4 'N' methods behave the
same way as the JDBC 3/JDBC 4 non-'N' methods with respect to NVARCHAR
data.
For more information on the sendStringParametersAsUnicode connection property, see Setting the Connection Properties.

Related

Websphere Data source UTF8 connection parameter

I have to define the UTF8 character encoding connection parameter in the websphere JDBC datasource settings.
I didn't find any option to configure the connection parameter
?useUnicode=yes&characterEncoding=UTF-8
Eg:
jdbc:sqlserver://localhost/DatabaseName?useUnicode=yes&characterEncoding=UTF-8
Is there any way to configure the characterEncoding connection parameter in the Websphere JDBC data source ?
The closest setting that I see on the Microsoft SQL Server JDBC driver is sendStringParametersAsUnicode with values of true or false, which appears to be a way of getting PreparedStatement.setString and a few other methods to supply parameters to the database as unicode prior to the introduction of methods such as PreparedStatement.setNString in JDBC 4.0, which would always use unicode.
https://learn.microsoft.com/en-us/sql/connect/jdbc/setting-the-connection-properties?view=sql-server-ver15
If the database supports setting the property "characterEncoding", you can simply create a custom datasource property for it, with the value you need. If the database supports supports url connection (as in your example), you can also just include it as part of your connection URL, which can also be set as a custom datasource property.

ORA-28562 data error truncation in oracle heterogenous?

I have created an Oracle heterogenous service to db2 using DG4ODBC.
try login using isql and select using this query
select *from workorder#maximo
I get a result set all of the data
but when I am login using sqlplus Oracle I get this error
this is my heterogenous init
and I try using HS_FDS_TRACE_LEVEL=DEBUG and get some column have a sql_null_value
This the sample of the log from debugging:
if any columns have null value then the data cannot be showing.
how I can show the data even though have a null value??
I am using Oracle 12c and db2 10.5
Try using:
HS_FDS_SQLLEN_INTERPRETATION = 32
(From Ocacle docs) This parameter is only valid for 64 bit platforms. ODBC standard specifies SQLLEN (of internal ODBC construct) being 64 bit on 64 bit platforms, but some ODBC driver managers and drivers violate this convention, and implement it as 32 bit. In order for the gateway to compensate their behavior, you need to specify HS_FDS_SQLLEN_INTERPRETATION=32 if you use these types of driver managers and driver.
It is unclear from your question the bitness of the Db2 odbc client, or whether the driver-manager or driver is using 32-bit or 64-bit internally for this. After changing this parameter you may need to re-initialise. A CLI trace of Db2 (google for instructions) may also expose this.
I've got this error when I was trying to load a TEXT data type from Postgres to Oracle VARCHAR2(4000) and the source data in the TEXT column was bigger than 4000 bytes.
One of available workarounds could be to map TEXT column to PL/SQL's VARCHAR2(32767) variable or maybe LONG, CLOB data type.

Incorrect encoding using jruby with datamapper

I'm trying to get data form a 2008r2 MSSql server using jruby and datamapper.
The only problem I've got this far is correct character coding in jruby.
Database uses Polish_CI_AS collation, testing field is populated with: "ą ę ś ć".
Fetching that field from within jruby results in: "uFFFD uFFFD uFFFD uFFFD" which are default replacement strings for utf-8.
I've tried setting the -E variable to windows-1250, it changes the characters displayed but as in Utf-8 they are displayed in the same manner. Also tried to include # encoding: Windows-1250, but it doesn’t help either.
I’m pretty sure it has something to do with datamapper or the db connection but jdbc does not supports (AFAIK) encoding variables.
UPDATE
My connection string: DataMapper.setup(:default, 'sqlserver://servername/database;instance=InstanceName;domain=DOMAIN')
The connection works well with MS JDBC, datamapper uses jTDS which uses UTF8 encoding as default.
I've checked the jTDS documentation and found that I needed to add: charset=cp1250; property at the end of my connection string. It all works well now.

Testing Connection Parameters with NHibernate

We have a program where users can specify their database connection parameters. The usual suspects including host, port, username, password, and table name. We are connecting to the database using NHibernate. What we'd like to do is be able to build the configuration with NHibernate and then test the connection parameters before continuing with other operations; notifying the user of failure.
Is this possible to do through NHibernate, or will it require using each database type we support's specific driver and creating a custom TestConnection() method for each type?
I realize this is an old post - but I guess an answer to a question never hurts.
I don't think there is a way to explicitly tell NHibernate to test out the connection string. However, when you instantiate the SessionFactory it will attempt to connect to the database. You could wrap your SessionFactory creation in a Try/Catch and handle the error that way.
I use Fluent NHibernate, but I'm sure the following example will still explain the situation.
Dim sf as SessionFactory
Try
sf = CreateSessionFactory()
Catch ex as FluentNHibernate.Cfg.FluentConfigurationException
Messagebox.Show(ex.InnerException.Message)
End Try
The ex.InnerException.Message contains the actual error and will tell you if:
The connection string was invalid
The server could not be found
The user/pass could not be authenticated
To configure Nhibernate you have two options:
Set the dialect when you are building the session factory. This will assign reasonable default value to Nhibernate's ADO and other configuration values.
Manually set the configuration values.
That said, at some point, you need to configure Nhibernate to use the appropriate driver for the database you want to talk to. Which means you need to be able to build Session Factories of different types (your supported database types). To do this you need more than just "host, port, username, password, and table name". You need to know the database type(Dialect).
If you intend to just try to connect the database with every driver available to you not knowing what the database type is, you may run into problems when the database and the dialect don't match. Imagine you use a SqlServer2008 dialect on SqlServer2005 machine. The difference in dialect can cause a particular SqlServer2008 feature you are using not to, obviously, work. Moreover, if you don't stick to basic SQL through out all your code, you may be generating Sql that works, say, in PostgreSql but not in SqlServer (Think sequences and such).
To learn more about configuring Nhibernate read:
Chapter 3: Session Factory Configuration. Specially sections 3.3, 3.4, 3.5 which talk about configuration parameters.
Last note, Nhibernate supports multiple databases. But, for complex domain layers where you rely on database specific constructs, your code doesn't.

SQL Server 2000 charset issues

Once again with the charset issues when talking to DB's :)
I have two enviroments running Zend Server. Bot of these communicate to a SQL Server 2000 using the mssql extension. None of them has any value given for the charset in the settings of the extension. For one it works and for the other one it returns data in the wrong encoding.
The problem became noticed when this data was beeing inserted into a MySQL database and it screamed with SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF6m' for column 'cust_lastname' at row 1.
I tried using SET NAMES utf8 to get the SQL Server connection to return the correct data, but it complains and says that NAMES is not a recognized SET statement. Looking around most people even recommend using this but it doesn't seem to be part of SQL Server 2000 :)
So, what should I do? How do I, WITHOUT fiddling with the SQL Server database/tables, tell it to send me the data in UTF-8 encoded format?
EDIT:
Some more info...
SQL Server uses the Finnish_Swedish_CI_AS collation
MySQL has every table in UTF-8 format and uses utf8_unicode_ci
I didn't find a good solution and ended up converting to and from utf8 in my application. If this is encapsulated within a class it doesn't riddle the code. But a way to actually tell the SQL server which encoding to use during communication would be better.

Resources