I am trying to write a simple Java
client program that uses koi8r as its character set, and keep on failing.
Class.forName("com.mysql.jdbc.Driver");
Connection conn2 = DriverManager.getConnection ("jdbc:mysql://localhost:3306/test","root",null);
Statement stmt = conn2.createStatement();
int result;
result = stmt.executeUpdate("SET CHARACTER SET koi8r");
stmt = conn2.createStatement();
result = stmt.executeUpdate("DROP TABLE IF EXISTS װֱֱֲֳֹּ, t1, t2");
stmt.close();
assertEquals(0, result);
I'm getting
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '???????, t1, t2' at line 1
When I put these commands in a script file and execute them using MySql client it works fine
SET CHARACTER SET koi8r
DROP TABLE IF EXISTS װֱֱֲֳֹּ, t1, t2
I sniffed the network and I saw the the jdbc connector sends it with ?????? to the server, so I guess I'm missing some setting to the connection.
Actually I tried (setEncoding, setCharactersEncoding, setConncetionCollation ...), but still failed.
You need to tell the JDBC driver which encoding it should use to transfer the characters over network. It namely defaults to platform default encoding which is in your case apparently not UTF-8.
You can do this by adding the following two query parameters to the JDBC URL:
jdbc:mysql://localhost:3306/test?useUnicode=yes&characterEncoding=UTF-8
See also the documentation.
Related
I agree that the database user privileges should be tuned to prevent him for running DML or DDL queries but I'm trying to do a similar thing from the client side. The JDBC side.
I downloaded Oracle driver found here.
While the driver and it's companion JARs are in the classpath, I ran the following piece test code:
Connection connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
// connection.setReadOnly(true); // Doesn't help
Statement statement = connection.createStatement();
statement.executeQuery("ALTER TABLE GELBANA_TEST.TABLE1 ADD HQ varchar2(40) DEFAULT 'NY'");
connection.rollBack();
But the column is added to the table !!
I can also drop the column.
Shouldn't this be enough to prevent the user from running DML or DDL queries ? I need to stop him from making any changes to the database. He should be allowed to only select data. I checked the connection URL parameters for something that could reject such queries but I found nothing close.
We are using SQL Server 2016 with a linked server to zDB2 (mainframe) via Microsoft OLE DB Provider for DB2 Version 5.0.
When executing a failing SQL statement remote on a linked server (zDB2) the error description is clear in SQL studio but useless in Java.
Example of statement (missing schema name):
EXEC (N'UPDATE TABLENAME SET COLUMN1=''SOMEVALUE'' WHERE COLUMN2= ''032'' ') AT ZDB2
Gives the following result in SQL Studio:
OLE DB provider "DB2OLEDB" for linked server "ZDB2" returned message "DB2GRP.TABLENAME IS AN UNDEFINED NAME SQLSTATE: 42704, SQLCODE: -204".
Msg 7215, Level 17, State 1, Line 6
Could not execute statement on remote server 'ZDB2'.
But the following result in a Java SQLException:
com.microsoft.sqlserver.jdbc.SQLServerException: Could not execute statement on remote server 'ZDB2'.
SQL State: S0001
SQL Error code: 7215
Using a debugger and inspecting the SQL Exception object, it seems the SQLException has no other data on the error.
How can I get a more useful explanation out of the SQLException on what went wrong besides "Could not execute statement on remote server" ?
And where is the documentation of what S0001 and 7215 means ? (I already googled)
Thank you in advance.
I believe the S0001 and 7215 are responses back from the Microsoft JDBC driver. The DB2 error info is "SQLSTATE: 42704, SQLCODE: -204" which is unfortunately not showing up in the Java output. It looks like the Microsoft driver is substituting it's own sqlstate/code instead of passing along DB2's.
The -204 is "name is an undefined name" (as is stated in the text before the sqlstate and code).
http://www.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/codes/src/tpc/db2z_n.html
Since you mention Java code, note that DB2 provides a JDBC driver for direct connectivity. That should at least eliminate the possibility of the MS driver interfering with the error codes returned by DB2. You typically have to get the driver and license file from your systems guys--AFAIK, they aren't publicly provided by IBM but they are included with DB2 for z/OS. But I'd recommend trying to use the IBM driver unless there's some compelling reason why you have to use the Microsoft driver--I am confused about the mention of both OLE DB Provider and JDBC.
Apparently errors from a linked server are stored as warnings on the statement rather than part of the SQLException when using Microsofts JDBC Driver.
This is how i did it:
try{
...
} catch (SQLException e) {
SQLWarning sqlWarning = currentStatement.getWarnings();
if (sqlWarning != null) {
warning = sqlWarning.getMessage();
}
}
I have a java web application that uses the next function to execute a stored procedure, it connects to SQL Server 2008:
Class.forName(sDriver_Reportes);
conn = DriverManager.getConnection(sDB_URL, sUSER, sPASS);
sQuery = "{call procGetResult(?)}";
proc = conn.prepareCall(sQuery);
proc.setString("pDate", sDate);
proc.execute();
rs = proc.getResultSet();
but it takes about 7 minutes to return the resultset, if I execute the sp it takes just 10 seconds to show the result.
I were looking for some similar case but only found post about parameter sniffing and connection pool but anyone seems to be like mi case because the sp is running fast, could you give me some info about where else to look about this issue.
Thank you in advance.
It seems to be a problem of SQL Server Parameter Sniffing. The first thing you need to check is the execution plan for your stored procedure.You can view it using the following icon in SQL Server Management Studio:
Now being exposed to the problem here are a few methods to address it:
Create SQL Server Stored Procedures using the WITH RECOMPILE Option
Use the SQL Server Hint OPTION (RECOMPILE) Use the SQL Server Hint
OPTION (OPTIMIZE FOR) Use Dummy Variables on SQL Server Stored
Procedures Disable SQL Server Parameter Sniffing at the Instance
Level Disable Parameter Sniffing for a Specific SQL Server Query
For implementation and better understanding you can refer the below link :
https://www.mssqltips.com/sqlservertip/3257/different-approaches-to-correct-sql-server-parameter-sniffing/
I am trying to connect to a database in Mariadb through a simple java application but the connection is told to be unsuccessful and an Exception is thrown. I have done the similar connection using mysql and it was working correctly. The problem is maybe with the driver here.
try{
Class.forName("org.mariadb.jdbc.Driver");
Connection connection = DriverManager.getConnection(
"jdbc:mariadb://localhost:3306/project", "root", "");
Statement statement = connection.createStatement();
String uname="xyz",pass="abc";
statement.executeUpdate("insert into user values('"+uname+"','"+pass+"')");}//end of try block
I looked up the internet for the help and came by that driver class provided by the MariaDB Client Library for Java Applications is not com.mysql.jdbc.Driver but org.mariadb.jdbc.Driver! I changed it accordingly but it seems the problem is with the very first line inside the try block. The driver is not loading at all.
Also, I have added the mysql jar file to the libraries of my java application as in the screen-shot below. Please help me through this.
It appears that you are trying to use jdbc:mariadb://... to establish a connection to a MariaDB server instance using the MySQL JDBC Driver. That probably won't work because the MySQL JDBC Driver would use jdbc:mysql://..., regardless of whether it is connecting to a MySQL server or a MariaDB server. That is, the connection string must match the driver that is being used (rather than the database server being accessed).
The MySQL and MariaDB drivers are supposed to be somewhat interchangeable, but it only seems prudent to use the MariaDB connector when accessing a MariaDB server. For what it's worth, the combination of mariadb-java-client-1.1.7.jar
and
Connection con = DriverManager.getConnection(
"jdbc:mariadb://localhost/project",
"root",
"whatever");
worked for me. I downloaded the MariaDB Client Library for Java from here:
https://downloads.mariadb.org/client-java/1.1.7/
which I arrived at via
https://downloads.mariadb.org/
Additional notes:
There is no need for a Class.forName() statement in your Java code.
The default configuration for MariaDB under Mageia may include the skip-networking directive in /etc/my.cnf. You will need to remove (or comment out) that directive if you want to connect to the database via JDBC because JDBC connections always look like "network" connections to MySQL/MariaDB, even if they are connections from localhost. (You may need to tweak the bind-address value to something like 0.0.0.0 as well.)
An additional note:
Exploring the MariaDB JDBC driver, I found this inside the url parsing file:
Project: https://github.com/MariaDB/mariadb-connector-j.git
File: src/main/java/org/mariadb/jdbc/UrlParser.java
public static UrlParser parse(final String url, Properties prop) throws SQLException {
....
if (url.startsWith("jdbc:mysql:")) {
UrlParser urlParser = new UrlParser();
parseInternal(urlParser, url, prop);
return urlParser;
} else {
if (url.startsWith("jdbc:mariadb:")) {
UrlParser urlParser = new UrlParser();
parseInternal(urlParser, "jdbc:mysql:" + url.substring(13), prop);
return urlParser;
}
}
As you can see, the string "jdbc:mariadb:" is always replaced with "jdbc:mysql:" internally. So when it comes to the MariaDB driver, whether it is :mariadb: or :mysql: it always gets parsed as "jdbc:mysql:".
No difference.
if (url.startsWith("jdbc:mariadb:")) {
....
parseInternal(urlParser, "jdbc:mysql:" + url.substring(13), prop);
....
Last time I used SQL with Java/Eclipse I had a SQL script linked to the Project.
This time, I connected to a different server using jdbc format (not localhost) and it connects correctly.
Now I need to get into this specific database named WInfo but I don't know how to do that.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
c = DriverManager.getConnection("jdbc:sqlserver://serverName:1433/;user=UserName;password=******;");
Use below connection string:
c = DriverManager.getConnection("jdbc:sqlserver://SERVERNAME:PORTNO;databaseName=DATABASENAME;
user=MyUserName;password=*****");
OR
c = DriverManager.getConnection("jdbc:sqlserver://SERVERNAME:PORTNO;databaseName=DATABASENAME",
MyUserName, MyPassword);