I'm converting (or trying to) an Ms AccessDB into derby.
When I extract the data from certain varchar / text / memo field from access they are filled with apostrophe, and mathematical symbols (percent, less than etc), and possible foreign characters
I need to keep these and I test for them so as I can use an 'escape sequence' to ensure they get put into the database.
However for now I am unable to get the data into the DB without it failing on these fields. When the SQL fails I output the SQL string, and cut and past it into ij. Then I modify just the first record, and it is always these characters that cause me grief.
I've tried to modify the strings by surrounding with "double quote marks" but that just gives a different error (stating that it has 'enounterd """ at line1 column x' which is always the first occurance of the double quote).
I haven't found a setting in derby to alter the behaviour for strings, yet. Is there one?
I have also tried to set the SQL statment to a preparedStatement then use the {call preparedStatement} again this fails also. I can't use the {escape "escape char} in a normal statment as derby just says incorrect syntax at me.
How do others manage to get user content with strange characters into a field in derby?
Do I need to change my field into a CLOB or something other than varchar / long Varchar?
Are my problems being caused by using the wrong characteset (eg iso rather UTF-8), how do I tell what it is, how to change it?
Below is a sample of the SQL insert that fails when I send it to derby (via my JAVA 'programme')
insert into S1.SORTIEDESSAI (OBS, DATEDUSORTIE, CONTREINDIC, FIN,
PDEVU, REFUS, INVDECISN, ADMIN, MOTIF_DE_LA_SORTIE, NOMVALIDEE,
DATEVALIDEE) values ('"0001/0001"' , '2007-07-15' , false , true ,
'"null"' , '"null"' , '"null"' , '"null"' , '"2. FIN DE L’ESSAI"' ,
'"DR SIMON"' , '2011-04-19' )
Note:
Actually I look at the above and notice that the order of columns names isn't good? It was OK yesterday, not sure why it would have changed? something to do with Access returning the column names in a random order from the resultSetMetaData, which would be a surprise.
for now I recomend any further answers to hold off whilst I sort this problem out, OK solved that problem, do I need to set another question about this behaviour....
Back to the main thread...
Ok as you can see on my SQL statement I have wrapped any varchar fields in double quotes. This always fails (even directly through ij). help help help...
I'm not quite sure what your question is, but in general you can input these characters by using a PreparedStatement of the form: INSERT INTO tablename (columnname) values (?), and then using the PreparedStatement.setString() method to supply your character data for that column.
Related
I am currently writing a Java web application which interfaces with an Oracle database. I am using PreparedStatements because Hibernate would complicate things too much.
Due to a bug in the program which is writing to the database, the field I need to search for has trailing spaces written to the value. I have surrounded the value with quotation marks to demonstrate the whitespace.
"testFTP_receipt521 "
When I do a select query with SQLDeveloper, I am able to get a result when I run:
...and yfs_organization.ORGANIZATION_KEY='testFTP_receipt521';
(no whitespace)
However, when I use a PreparedStatement, I get no results when I try:
...and yfs_organization.ORGANIZATION_KEY=?");
preparedStatement.setString(1, "testFTP_receipt521");
(no whitespace)
and when I try:
...and yfs_organization.ORGANIZATION_KEY=?");
preparedStatement.setString(1, "testFTP_receipt521 ");
(with whitespace)
Are there any ways that I can query for this result with a PreparedStatement, or should I try another approach?
Thanks for all your help.
Due to a bug in the program which is writing to the database, the field I need to search for has trailing spaces
Maybe, given the circumstances, and if your version of Oracle is recent enough, you might consider adding a virtual column to your table containing the correct value?
ALTER TABLE yfs_organization ADD (
ORGANIZATION_KEY_FIXED VARCHAR(80)
GENERATED ALWAYS AS (TRIM(ORGANIZATION_KEY)) VIRTUAL
);
Then in your code, the only change will be to use the ORGANIZATION_KEY_FIXED to query the DB:
SELECT ID,ORGANIZATION_KEY_FIXED
FROM yfs_organization
WHERE ORGANIZATION_KEY_FIXED='testFTP_receipt521'
(try it on http://sqlfiddle.com/#!4/8251d/1)
This might avoid to scatter around your application the code required to work around that bug. And might ease the transition once it will be fixed.
As an added benefice, you could add index on virtual columns if you need too.
Maybe you can use it like this...
...and yfs_organization.ORGANIZATION_KEY like '%testFTP_receipt521%';
this way returns you all reg where contains 'testFTP_receipt521' independently of whitespace.
Antoher thing that i saw in your code in this part
...and yfs_organization.ORGANIZATION_KEY=?");
preparedStatement.setString(1, "testFTP_receipt521");
i thing this is the correct way
...and yfs_organization.ORGANIZATION_KEY='?'");
you need to put quotes around the criteria
If you have the ability to modify the query, you can TRIM(...) the column value and perform the comparison. For example:
...and TRIM(yfs_organization.ORGANIZATION_KEY)=?");
Hope it helps.
I am trying to update the records in database according to data read from an Excel sheet. I have more than 50 columns in db whose column names are stored in an array columnNames[].
I use following code to create the Sql query.
String sqlUpdate= "Update "+tableName+
" set "+columnNames[0]+"=?";
for (int i=1;i<columnCount;i++)
{
sqlUpdate= sqlUpdate+","+columnNames[i]+"=?";
}
sqlUpdate= sqlUpdate+
" where demand_id=?";
the equivalent query obtained to printing it on console is :
Update fulfillment_plan set DEMAND_ID=?,SBU=?,PROJ_DOMAIN=?,JOBCODE=?,INDENT_STATUS=?,JC_CREATED_ON=?,PROJECT_NAME=?,CUSTOMER_NAME=?,GROUP_CUSTOMER=?,US_DEMANDS=?,SUITE_NAME=?,ROLE_NAME=?,LOCATION=?,COUNTRY=?,GEO=?,AREA=?,OPEN_POS=?,PRODUCT=?,DEMAND_TYPE=?,POSITIONS_TO_FULFILL_Q4=?,FULFILLMENT_PLAN_Q4=?,TA_STATUS_Q4=?,POSITIONS_TO_FULFILL_Q3=?,FULFILLMENT_PLAN_Q3=?,TA_STATUS_Q3=?,POSITIONS_TO_FULFILL_Q2=?,FULFILLMENT_PLAN_Q2=?,TA_STATUS_Q2=?,POSITIONS_TO_FULFILL_Q1=?,FULFILLMENT_PLAN_Q1=?,TA_STATUS_Q1=?,NET_ADD_TYPE=?,ESSENTIAL_SKILL=?,SUITE_SKILLS=?,ADDITIONAL_SKILLS=?,POSITIONS_WITH_PROPOSALS=?,POSITIONS_WITHOUT_PROPOSALS=?,DEM_ST_DATE=?,OVER_DUE_STATUS=?,OVERDUE_DAYS=?,LEAD_TIME_DAYS=?,LEAD TIME BUCKET=?,DEM_END_DATE=?,CREATED_ON=?,INDENT_CREATED_ON=?,EBD=?,OPPORTUNITYID=?,LOAD_DATE=?,PROJECT_NUMBER=?,CUSTOMER_NO=?,CUSTOMER_SUB_GEO=?,DEMAND_STATUS=?,ENGAGEMENT_TYPE=?,INVOICE_TYPE=?,INDENT_CLASSIFICATIONS=?,PROJ_STAT=?,EFD_SLA=?,RM_EMP_NAME=?,MONTH=?,QUARTER=?,YEAR=?,ACCOUNT_ID=?,ACCOUNT_TEXT=?,STATUS=? where demand_id=?
Then i have set the values to the '?' and on executing the above prepared statement in am getting the "missing equal sign" error. I have been looking into it for around 3 hours now and am not able to solve it. Kindly help.
I suspect this is due to the LEAD TIME BUCKET column name, which should either have underscores (like the other column names) or be escaped somehow - the spaces within the column name are causing the error. It would be better to have underscores in order to be consistent with your other columns, and to make the SQL simpler.
(I'd also suggest adding spaces within your SQL - e.g. one after every comma - so that the SQL can be reformatted in a text editor by line-breaking on spaces, making it easier to read. I'd have more whitespace in the Java code too, but that's clearly a matter of personal/team preference.)
I'm using Netbeans building a web application using Java, JSP that handle a database with Hebrew fields.
The DDL is as follows:
String cityTable = "CREATE TABLE IF NOT EXISTS hebrew_test.table ("
+"id int(11) NOT NULL AUTO_INCREMENT,"
+"en varchar(30) NOT NULL,"
+"he varchar(30) COLLATE utf8_bin NOT NULL,"
+"PRIMARY KEY (id)"
+") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;";
String insert = "INSERT INTO hebrew_test.table (en, he) VALUES ('A','a')";
String insert2 = "INSERT INTO hebrew_test.table (en, he) VALUES ('B','ב')";
String insert3 = "INSERT INTO hebrew_test.table (en, he) VALUES ('C','אבג')";
executeSQLCommand(cityTable);
executeSQLCommand(insert);
executeSQLCommand(insert2);
executeSQLCommand(insert3);
The output tabel I get:
1 A a
2 B ?
3 C ???
Instead of:
1 A a
2 B ב
3 C אבג
I tried Hebrew appears as question marks in Netbeans, but that isn't the same problem. I get the question marks in the table.
Also I defined the table to be in UTF8_bin as you can see in the above code.
You need to tell the JDBC driver to use UTF-8 encoding while decoding the characters representing the SQL query to bytes. You can do that by adding useUnicode=yes and characterEncoding=UTF-8 query parameters to the JDBC connection URL.
jdbc:mysql://localhost:3306/db_name?useUnicode=yes&characterEncoding=UTF-8
It will otherwise use the operating system platform default charset. The MySQL JDBC driver is itself well aware about the encoding used in both the client side (where the JDBC code runs) and the server side (where the DB table is). Any character which is not covered by the charset used by the DB table will be replaced by a question mark.
See also:
Spring Encoding with CharacterEncodingFilter in web.xml
You're including your values directly into the SQL. That's always a bad idea. Use a PreparedStatement, parameterized SQL, and set the values as parameters. It may not fix the problem - but it's definitely the first thing to attempt, as you should be using parameterized SQL anyway. (Parameterized SQL avoids SQL injection attacks, separates code from data, and avoids unnecessary conversions.)
Next, you should work out exactly where the problem is really occurring:
Make sure that the value you're trying to insert is correct.
Check that the value you retrieve is correct.
Check what's in your web response using Wireshark - check the declared encoding and what's in the actual data
When checking the values, you should iterate over each character in the string and print out the value as a UTF-16 code unit (either use toCharArray() or use charAt() in a loop). Just printing the value to the console leaves too much chance of other problems.
EDIT: For a little context of why I wrote this as an answer:
In my experience, including string values as parameters rather than directly into SQL can sometimes avoid such issues (and is of course better for security reasons etc).
In my experience, diagnosing whether the problem is at the database side or the web side is also important. This diagnosis is best done via logging the exact UTF-16 code units being used, not just strings (as otherwise further encoding issues during logging or console output can occur).
In my experience, problems like this can easily occur at either insert or read code paths.
All of this is important as a way of moving the OP forward, not just in a comment-like request for more information.
I am trying to insert string-values larger than 5500 characters into a MSSQL 2008 database. I get the error
String or binary data would be truncated.
when I try to insert these values even though the data type of the column is declared nvarchar(max). Is there a cap on the string-size that I can enter? If so, what would be a solution to this problem?
EDIT
When i manually enter the data via mgmt studio it works. However, I'm performing the updates via JDBC-driver & prepared statements.
My query is of the form:
UPDATE table SET columnX = value1 WHERE columnX = value2;
I add this statement to a batch, and once every 1000 statements I execute them.
value1 in this case contains a large amount of characters.
columnX is definitely defined as nvarchar(max)
Microsoft encourages us to use the SQLServerPreparedStatement to modify large-value-types like varchar(max).
http://msdn.microsoft.com/en-us/library/ms378813.aspx
You could also use a stored procedure to solve the problem, that is what I did, when I had similar problems with JDBC/Pentaho.
You could write a stored procedure on the sql-server that fulfills the task. And just call that stored procedure from your Java-code.
I hope that helps!
I have a field with varchar(100) in mysql, I want to store first 100 characters because my data length is 200 characters(ignore last 100 character).I doesn't want to change my source code. Which is possible in MS-Access and MS Server but I want to do this in mysql.
I am applying this in java with hibernate, means I am not writing insertion code for this. Here I am just using save() method and its throwing "Large data".
I have got Exception-
Caused by: java.sql.BatchUpdateException: Data truncation: Data too long for column 'FBUrl' at row 1
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1527)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1065)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
glb.chatmeter.exception.AdException: Could not Save Facebook page Data.
Note: An hour after the below, the question was edited with a substantial change. This answer answered the question as it was originally, but doesn't address the edited version.
You can use substring:
INSERT INTO MyTable (Myfield) values (SUBSTRING('long string', 1, 100))
The pos parameter starts at 1 (oddly), and it's okay if the len parameter is larger than the length of what you're actually inserting.
You can use SUBSTRING() to trim inserts:
INSERT INTO table (column) VALUES (SUBSTRING("your data...", 1, 100))
try this
SELECT INSERT('your string', 0, 100, '');
REFERENCE
The only way to do it without changing the source code is to fiddle with the configuration of the MySQL server. More specifically, the sql_mode variable:
http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html
I believe you have to set STRICT_TRANS_TABLES:
For STRICT_TRANS_TABLES, MySQL
converts an invalid value to the
closest valid value for the column and
insert the adjusted value. If a value
is missing, MySQL inserts the implicit
default value for the column data
type. In either case, MySQL generates
a warning rather than an error and
continues processing the statement.
Implicit defaults are described in
Section 10.1.4, “Data Type Default
Values”.
However, it's important to note that this setting will affect many other things. The only reason I see not to change the source code is that you don't have access to it, and in such case you can probably just enlarge the DB column.