I have a Java application that uses JDBC (via JPA) that was connecting to a development database using hostname, port and Oracle SID, like this:
jdbc:oracle:thin:#oracle.hostserver1.mydomain.ca:1521:XYZ
XYZ was the Oracle SID. Now I need to connect to a different Oracle database that does not use a SID, but uses an Oracle "Service Name" instead.
I tried this but it doesn't work:
jdbc:oracle:thin:#oracle.hostserver2.mydomain.ca:1522:ABCD
ABCD is the Service Name of the other database.
What am I doing wrong?
http://download.oracle.com/docs/cd/B28359_01/java.111/b31224/urls.htm#BEIDHCBA
Thin-style Service Name Syntax
Thin-style service names are supported only by the JDBC Thin driver. The syntax is:
#//host_name:port_number/service_name
For example:
jdbc:oracle:thin:scott/tiger#//myhost:1521/myservicename
So I would try:
jdbc:oracle:thin:#//oracle.hostserver2.mydomain.ca:1522/ABCD
Also, per Robert Greathouse's answer, you can also specify the TNS name in the JDBC URL as below:
jdbc:oracle:thin:#(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL=TCP)(HOST=blah.example.com)(PORT=1521)))(CONNECT_DATA=(SID=BLAHSID)(GLOBAL_NAME=BLAHSID.WORLD)(SERVER=DEDICATED)))
So there are two easy ways to make this work. The solution posted by Bert F works fine if you don't need to supply any other special Oracle-specific connection properties. The format for that is:
jdbc:oracle:thin:#//HOSTNAME:PORT/SERVICENAME
However, if you need to supply other Oracle-specific connection properties then you need to use the long TNSNAMES style. I had to do this recently to enable Oracle shared connections (where the server does its own connection pooling). The TNS format is:
jdbc:oracle:thin:#(description=(address=(host=HOSTNAME)(protocol=tcp)(port=PORT))(connect_data=(service_name=SERVICENAME)(server=SHARED)))
If you're familiar with the Oracle TNSNAMES file format, then this should look familiar to you. If not then just Google it for the details.
You can also specify the TNS name in the JDBC URL as below
jdbc:oracle:thin:#(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL=TCP)(HOST=blah.example.com)(PORT=1521)))(CONNECT_DATA=(SID=BLAHSID)(GLOBAL_NAME=BLAHSID.WORLD)(SERVER=DEDICATED)))
Try this: jdbc:oracle:thin:#oracle.hostserver2.mydomain.ca:1522/ABCD
Edit: per comment below this is actualy correct: jdbc:oracle:thin:#//oracle.hostserver2.mydomain.ca:1522/ABCD (note the //)
Here is a link to a helpful article
This discussion helped me resolve the issue I was struggling with for days. I looked around all over the internet until I found the answered by Jim Tough on May 18 '11 at 15:17. With that answer I was able to connect. Now I want to give back and help others with a complete example. Here goes:
import java.sql.*;
public class MyDBConnect {
public static void main(String[] args) throws SQLException {
try {
String dbURL = "jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=whatEverYourHostNameIs)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=yourServiceName)))";
String strUserID = "yourUserId";
String strPassword = "yourPassword";
Connection myConnection=DriverManager.getConnection(dbURL,strUserID,strPassword);
Statement sqlStatement = myConnection.createStatement();
String readRecordSQL = "select * from sa_work_order where WORK_ORDER_NO = '1503090' ";
ResultSet myResultSet = sqlStatement.executeQuery(readRecordSQL);
while (myResultSet.next()) {
System.out.println("Record values: " + myResultSet.getString("WORK_ORDER_NO"));
}
myResultSet.close();
myConnection.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
In case you are using eclipse to connect oracle without SID. There are two drivers to select i.e., Oracle thin driver and other is other driver. Select other drivers and enter service name in database column. Now you can connect directly using service name without SID.
When using dag instead of thin, the syntax below pointing to service name worked for me. The jdbc:thin solutions above did not work.
jdbc:dag:oracle://HOSTNAME:1521;ServiceName=SERVICE_NAME
This should be working: jdbc:oracle:thin//hostname:Port/ServiceName=SERVICE_NAME
Related
mvn:net.sourceforge.jtds/jtds/1.3.1-patch-20190523/jar
to save to a Microsoft SQL Server database.
Actually this JDBC driver is provided by Talend. For various reasons, I have some Java JDBC code which saves blobs to the database. This works fine with an Oracle DB.
try (Connection con = DriverManager.getConnection(this.connectionString, this.user, this.pw)) {
insert(con, ags, snr, productVersion, nummer, inhalt, this.migrationsBenutzer, format, daten);
}
public long insert(Connection con, String ags, String snr, int productVersion ,int nummer,String inhalt, String benutzer, String format, byte[] daten) throws SQLException {
long result = 0;
String timestamp = now();
try {
Blob blob = con.createBlob();
blob.setBytes(1, daten);
PreparedStatement ps = con.prepareStatement(this.insert);
...
ps.setBlob(9, blob);
result = ps.executeUpdate();
However when I call the method with a connection string for jtds:
jdbc:jtds:sqlserver://:1433;databaseName=
I get this exception
Exception in thread "main" java.lang.AbstractMethodError
at net.sourceforge.jtds.jdbc.JtdsConnection.createBlob(JtdsConnection.java:2776)
at de.iteos.dao.BildspeichernDAO.insert(BildspeichernDAO.java:60)
What can I do? If feasible I want to keep the method a generic as possible. Do I have to switch to another JDBC driver? I have read somewhere that this could be solved with a validation query. For this I would have to implement two different DataSources for Oracle and SQL Server right?
The problem is that jTDS is - as far as I know - no longer maintained, and available versions are stuck on JDBC 3.0 (Java 1.4) support. The method Connection.createBlob you're trying to call was introduced in JDBC 4.0 (Java 6). Attempts to call this method on a driver that was compiled against the JDBC 3.0 API will result in AbstractMethodError as the method from JDBC 4.0 (or higher) is not implemented.
The simplest and best solution is probably to switch to the Microsoft SQL Server JDBC driver.
Alternatively, you need to switch to the JDBC 3.0 options for populating a blob, that is, using the PreparedStatement.setBinaryStream(int, InputStream, int) method (not to be confused with setBinaryStream(int, InputStream) or setBinaryStream(int, InputStream, long) introduced in JDBC 4.0!), or possibly setBytes(int, byte[]), or using driver specific methods for creating blobs.
The validation query solution you mention doesn't apply here, that solves a problem with Connection.isValid that the data source implementation in some Tomcat versions calls by default, unless you configure a validation query. It has the same underlying cause (the isValid method was also introduced in JDBC 4.0).
I'm not sure what you mean with "I would have to implement two different DataSources for Oracle and SQL Server right?", you cannot use one and the same data source for two different databases, so you would need to configure two different instances anyway.
It is very easy and well documentented how to run H2 in server mode. Just code:
Server.createTcpServer().start();
Very easy. But I'm unable to find an answer on:
how to give the created database an other name than 'test', because this is the default name.
how to persist the data. As it seems, this way the server starts an in-memory DB. But what I'm looking for is something that persists the data permanently.
Any idea?
As described in Connecting to a Database using JDBC, the database file name may be specified in the database URL, for example
jdbc:h2:tcp://localhost/~/src/java/MyDatabase;IFEXISTS=TRUE
Data will be stored in the file MyDatabase,h2.db.
See Opening a Database Only if it Already Exists for the effect of specifying ;IFEXISTS=TRUE. Compare the URL with these embedded mode examples.
Addendum: Where will you give this URL?
Once the server is started, you can connect to the running database by passing the URL to your preferred client, as suggested here, or programmatically via java.sql.Connection, as shown here.
After an other day and switch to derby I find a solution for this problem. I don't know why this is not handled by the H2 documention, but ok.
First at all. For me the connection url and the physical location of the DB-Files are different things. And I don't like this file things, because I want to take a look in the db on the fly.
So, whats to is this
private Server startDb() {
Server retVal = null;
try {
final String userDir = System.getProperty("user.dir");
// System.setProperty("h2.baseDir", userDir + "/data/jumpstart");
retVal = Server.createTcpServer("-baseDir", userDir + "/data/jumpstart");
retVal.start();
Connection conn = null;
try {
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/jumpstart", "sa", "sa");
} finally {
if (conn != null)
conn.close();
}
} catch (final Exception ex) {
}
return retVal;
}
As you can see here, the files of the db will be stored in the directoy /data/jumpstart.
The URL of JDBC connect hide this detail. It only address the the DB with name jumpstart.
That it is.
HTH
Andreas
Disclaimer: I don't actually know anything about nether Oracle nor Java. The issue is in a project that some other developer completed at some point in time and then left the company. Now I have to setup webserver, database and get it all up and running.
the code is approx this:
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:<user>/<password>#localhost:1521:xe");
OracleConnection ocon = (OracleConnection)ods.getConnection();
OracleStatement stmt = (OracleStatement)ocon.createStatement();
OracleResultSet rs = (OracleResultSet)stmt.executeQuery("SELECT POLLID, QUESTION, ISMULTISELECT FROM POLL WHERE POLLID = " + pollID);
if (!rs.next()) {
System.out.println("No rows found.");
return false;
}
this._PollID = rs.getInt("POLLID");
this._Question = rs.getString("QUESTION");
this._IsMultiSelect = rs.getBoolean("ISMULTISELECT");
The POLLID and ISMULTISELECT columns return correct values as expected. The QUESTION seem to always return empty string. The value in the DB is obviously not empty.
The rs.getAsciiStream("QUESTION").available() also returns zero.
Am I missing something completely obvious here?
EDIT:
sqlplus returns varchar2 value just fine
connecting via odbc (as opposed to thin) also makes things work
so no Exceptions, you are not using reserved words...maybe try to use other driver, or select into other table and experiment start with empty QUESTION column, then add some value and debug.
Thanks to everyone who replied. At this point it seems issue is between thin driver and XE version of Oracle. Unfortunately we don't have full version kickin' around (we are primarily ASP.NET/MS SQL developers), so we'll have to stick with ODBC driver for now and hope issue will magically resolve itself when we push it to live environment (hosted by third party). Very crappy assumption to make, but at this point I see no other options....
I had the same exact issue and found that the root of the problem comes from the orai18n.jar. once i removed this from my classpath, the issue went away.
I have the same problem. I do not have access to the driver that is used because the connection is taken from a Weblogic server using JNDI. I cannot remove any .jar from the server neither.
The workaround I found :
String value = new String(resultset.getBytes());
Make sure you use the right encoding if required :
String value = new String(resultset.getBytes(), [CHARSET])
I had this same issue with eclise GCJ ( Stock centos6 ) and mysql-connector with the same concatenated queries. The problem was solved with reverting back to openJDK.
I had the same issue. "getInt()" would return correct value from Oracle 9i DB, but using "getString()" would result into empty string, no matter how many times i ran, within eclipse or outside on seperate Tomcat or other servers.
After going through a lot of various threads, and quite a few trials, I came to the conclusion that the issue is with the version of ojdbc6.jar that I was using. Earlier, I was using ojdbc6.jar with Oracle version 12.1.0.1., which is not so good for connecting to OLD Oracle 9i DB. After realising, I switched on to ojdbc6.jar from Oracle 11.2.0.3 and it worked like a charm.
Hope it helps. cheers!
Converting to ODB.NET from System.Data.OracleClient and need help converting my connection string. Here is what I use with System.Data.OracleClient.
SERVER=(DESCRIPTION_LIST=(LOAD_BALANCE=yes)(FAILOVER=ON)(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.80)(PORT=9960))(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.81)(PORT=9960)))(CONNECT_DATA=(SERVICE_NAME=tactota))));uid=XXXXXXX;pwd=XXXXXXXX"
Here is what I have gotten to work with ODB.NET, but does not implement the other features of the above connection string.
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.80)(PORT=9960)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=tactota)));User Id=XXXXXXXX;Password=XXXXXXXX;
Here is what I got when I tried to roll them together, but needless to say it did not work.
Data Source=(LOAD_BALANCE=yes)(FAILOVER=ON)(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.80)(PORT=9960))(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.81)(PORT=9960)))(CONNECT_DATA=(SERVICE_NAME=tactota))); User Id=XXXXXX;Password=XXXXX;
Thanks!
Dave
Finally got it to work! Here is what I came up with
Data Source=(DESCRIPTION=(LOAD_BALANCE=yes)(FAILOVER=ON)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.80)(PORT=9960))(ADDRESS=(PROTOCOL=TCP)(HOST=172.26.140.81)(PORT=9960)))(CONNECT_DATA=(SERVICE_NAME=tactota))); User Id=XXXXXXX;Password=XXXXXXXX;
I've set up system DSNs, which I can use from other ODBC apps (e.g. iQueryODBC), but in mono, I get "Data source name not found and n" (sic).
I am using "DSN=myodbc" for the connection string, via the connection string builder.
OSX 10.4
Latest Mono packages - 2.4.2.3.
Anyone ever got ODBC working on Mono/ OSX?
(Oh - for what it is worth - and I am fairly certain it is not relevant - the DSN is for MySql 5 driver.)
Full code:
public static void Main (string[] args)
{
OdbcConnectionStringBuilder csb = new OdbcConnectionStringBuilder();
csb.Dsn = args[0];
DataSet d = GetDataSet(csb.ConnectionString , "SELECT * FROM tbl");
Console.WriteLine (d.Tables.Count);
}
public static DataSet GetDataSet(string connectionString, string queryString)
{
Console.WriteLine("GetDataSetFromAdapter(" + connectionString + ")");
DataSet dataSet = new DataSet();
using (OdbcConnection connection = new OdbcConnection(connectionString))
{
OdbcDataAdapter adapter = new OdbcDataAdapter(queryString, connection);
// Open the connection and fill the DataSet.
try
{
connection.Open();
adapter.Fill(dataSet);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return dataSet;
}
In the mono website are a example may can help you.
ODBC-Mono.Net
I think I have seen your post on the Mono mailing list about this but was too busy to respond at the time.
I have used both the ODBC interface and the native connector to connect to MySQL databases for Mono on Mac OS X, Linux, Windows and Solaris (and only ever had issues with an old build of Mono under Solaris).
Because of a problem I encountered with a production environment I switched to using the native MySQL connector some time ago though (I downloaded and built it using Mono Develop without issue).
This is an example of how I used the ODBC interface:
string connectionString = "DRIVER={MySQL ODBC 3.51 Driver};"
+ "SERVER=localhost;"
+ "DATABASE=myDatabase;"
+ "UID=root;"
+ "PASSWORD=p4ssw0rd;";
// Connect to database using ODBC Driver
OdbcConnection dbConnection = new OdbcConnection(connectionString);
dbConnection.Open();
// Execute SQL using the ODBC interface
OdbcCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = sql
OdbcDataReader dbReader = dbCommand.ExecuteReader();
// Get the result and put it into a hashtable (as an example)
ArrayList arrayList = new ArrayList();
int i = 0;
while(dbReader.Read()) {
arrayList.Add(new Hashtable());
Hashtable hashtable = (Hashtable) arrayList[i];
for (int j = 0; j < dbReader.FieldCount; j++) {
hashtable.Add(dbReader.GetName( j ).ToString(), dbReader.GetValue( j ));
}
i++;
}
// Free up resources
dbReader.Close();
dbReader = null;
dbCommand.Dispose();
dbCommand = null;
// Close DB Connection
dbConnection.Close();
If the example does not work (for some non-obvious reason) comment and let me know and I will test it and/or provide a tested example of using the native MySQL provider if that would be helpful.
Thanks for the advice, but 'fraid it does't work - Connection.Open fails, exactly as before, with "Data source name not found..." It thinks the DSN doesn't exist, but... it does, because other apps (non Mono) can use it. I've dived into the Mono source code, for OdbcConnection.Open, but it is just a wrapper for some native code, which I don't have the source for.
Note that I am using totally standard, generic code - a classic 'example' so it is not a question (I'm fairly certain) of not knowing HOW to do it - I am doing it correctly, but it just doesn't work as per the examples elsewhere on the net, because the Odbc connection is asking for a named DSN, and is being told by the native code that the DSN doesn't exist.
Note also that using a DSN-less connection produces EXACTLY the same error - the native code provider still looks for a matching DSN, which (obviously, in this case) it doesn't find because there isn't a DSN called "DATABASE=myDatabase...".
I'm guessing this is OSX 10.4 related, so... I'm maybe not going to find an answer.
I also tried the native MySql connector, but it failed to build. Again, may be 10.4 related. Maybe this is the excuse I need to upgrade... which would (of course!) require a new MacBook... mmmm... shiny!!
Thanks again for the advice, chaps.
For the benefit of anyone else driving by this, you CAN compile the native MySql connector on 10.4. The "sln" which you download from MySql.com contains a lot of other stuff which isn't required, and doesn't compile! But don't be put off - just keep removing projects from the solution until it compiles, and then grab MySql.Data.DLL to add to your project. (You don't have to add it to the GAC - just put it in the "bin" directory of your project, and reference it by file.)
#Iain - thanks for your advice again. I have explained to the Mrs that "a nice man on the internet" said that the only solution is a new MacBook Pro and she is thinking about it!