Invalid character encountered error - selecting rows - java

I am trying to get rows from table using SQLDeveloper by writing simple query:
SELECT * FROM agreements WHERE agreementkey = 1;
SELECT * FROM agreements WHERE agreementkey = 4;
but getting invalid character encountered error. It's not a problem with query(working using other keys, i.e. agreementkey = 3) but with XMLType column in this table - there is something wrong with data in some rows. Is there a way to select this affected row(I know keys of this affected rows) using queries? Maybe export to file or something? Solution of copying value manually is not acceptable.

Create an empty copy of the table and then run an INSERT into it based on a select from the original table but do it using the DML error logging clause.
This should show you any rows that fail to load and the reason for the failure.
CREATE TABLE test_agreements
AS SELECT * FROM agreements
WHERE ROWNUM <1;
INSERT INTO test_agreements
SELECT *
FROM agreements
LOG ERRORS REJECT LIMIT UNLIMITED
This will create you an error logging table called ERR$TEST_AGREEMENTS which you can query to find the problem rows.

Problem is in WHERE key = 1 cause key is a Reserve Word in Oracle. You should escape it like
SELECT * FROM table WHERE "key" = 1;

KEY is a reserved word so to overcome that you need to use double quotes "".
SELECT * FROM table WHERE "key" = 1;

I think the problem can be solved by putting the argument in quotes:
SELECT * FROM agreements WHERE agreementkey = "1";
I wish I were familiar with XML, but I have run into this with VARCHAR2 columns that are supposed to have all numeric values. Oracle looks at the request
where agreementkey = 1
and tries to convert agreementkey to a number rather than 1 to a varchar2.

If the database contains invalid characters I would try one the following:
Maybe the solution of BriteSponge will work, using an insert statemant with error logging clause.
Use datapump to export the data to a file. I think the log will contain information to identify the invalid columns.
There was a tool called "character set scanner" that checked the characters of the data of a table, here is some documentation: CSSCAN. Or maybe you can use the Database Migration Assistent for Unicode (DMU) mentioned in the same manual.
4- You can write a small PL/SQL program that retrieves the rows row by row and in case of an error catches the exception and notifies you about the row.
DECLARE
invalid_character_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_character_detected, ???); begin
for SELECT rowid into rec FROM agreements do begin
for
SELECT * into dummy
FROM agreements
where rowid=rec.rowid
do
null;
end loop;
except
WHEN invalid_character_detected THEN
dbms_ouput.put_line(rec.rowid)
end;
end loop;
end;
I did not compile and test the program. ??? is the (negative) error code, e.g. -XXXXX if the error is ORA-XXXXX

Related

Checking if table exist or not

I am retrieving data from database using jdbc. In my code I am using 3-4 tables to get data. But sometimes if table is not present in database my code gives exception. How to handle this situation. I want my code to continue working for other tables even if one table is not present. Please help.
I have wrote a code like this
sql="select * from table"
now Result set and all.
If table is not present in database it give exception that no such table. I want to handle it. In this code I cannot take tables which are already present in advance . I want to check here itself if table is there or not.
Please do not mark it as a duplicate question. The link you shared doesnot give me required answer as in that question they are executing queries in database not through JDBC code
For Sybase ASE the easiest/quickest method would consist of querying the sysobjects table in the database where you expect the (user-defined) table to reside:
select 1 from sysobjects where name = 'table-name' and type = 'U'
if a record is returned => table exists
if no record is returned => table does not exist
How you use the (above) query is up to you ...
return a 0/1-row result set to your client
assign a value to a #variable
place in a if [not] exists(...) construct
use in a case statement
If you know for a fact that there won't be any other object types (eg, proc, trigger, view, UDF) in the database with the name in question then you could also use the object_id() function, eg:
select object_id('table-name')
if you receive a number => the object exists
if you receive a NULL => the object does not exist
While object_id() will obtain an object's id from the sysobjects table, it does not check for the object type, eg, the (above) query will return a number if there's a stored proc named 'table-name'.
As with the select/sysobjects query, how you use the function call in your code is up to you (eg, result set, populate #variable, if [not] exists() construct, case statement).
So, addressing the additional details provided in the comments ...
Assuming you're submitting a single batch that needs to determine table existence prior to running the desired query(s):
-- if table exists, run query(s); obviously if table does not exist then query(s) is not run
if exists(select 1 from sysobjects where name = 'table-name' and type = 'U')
begin
execute("select * from table-name")
end
execute() is required to keep the optimizer from generating an error that the table does not exist, ie, the query is not parsed/compiled unless the execute() is actually invoked
If your application can be written to use multiple batches, something like the following should also work:
# application specific code; I don't work with java but the gist of the operation would be ...
run-query-in-db("select 1 from sysobjects where name = 'table-name' and type = 'U'")
if-query-returns-a-row
then
run-query-in-db("select * from table-name")
fi
This is the way of checking if the table exists and drop it:
IF EXISTS (
SELECT 1
FROM sysobjects
WHERE name = 'a_table'
AND type = 'U'
)
DROP TABLE a_table
GO
And this is how to check if a table exists and create it.
IF NOT EXISTS (
SELECT 1
FROM sysobjects
WHERE name = 'a_table'
AND type = 'U'
)
EXECUTE("CREATE TABLE a_table (
col1 int not null,
col2 int null
)")
GO
(They are different because in table-drop a temporary table gets created, so if you try to create a new one you will get an exception that it already exists)
Before running the query which has some risk in table not existing, run the following sql query and check if the number of results is >= 1. if it is >= 1 then you are safe to execute the normal query. otherwise, do something to handle this situation.
SELECT count(*)
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'name_of_table')
I am no expert in Sybase but take a look at this,
exec sp_tables '%', '%', 'master', "'TABLE'"
Sybase Admin

Adding a column from another table into existing SQL/query statement

Currently, I have a query that I run in my java code that displays just a simple grid output of columns with the corresponding data for those specific fields. I am reading 2 tables that all have the same column names. I need to add just 1 column to that grid, but the field name resides on a different table. How would I add this to my existing query?
This is my current query that I execute in the Java:
SELECT TRNSP_EQP_EIN, TRNSP_EQP_ID, PRE_EQP_ID, EQP_GRP, AAR_CT_C,
AAR_MCHDSG_C,BLD_D, REBLD_D
FROM EQ.TE_TRNSP_EQPACTV A
WHERE TRNSP_EQP_ID = ‘BNSF0000000123’
UNION
SELECT TRNSP_EQP_EIN, TRNSP_EQP_ID, PRE_EQP_ID, EQP_GRP, AAR_CT_C,
AAR_MCHDSG_C,BLD_D, REBLD_D
FROM EQ.TE_TRNSP_EQPHIST A
WHERE A.TRNSP_EQP_ID = ‘ABC0123’
ORDER BY TRNSP_EQP_EFF_TS
WITH UR
Below is the information that I am trying to add to the grid to the existing SQL.
Table: EQ.TE_LOCO_EQP
Field: DEL_RSN_CD
You need to provide us with the full field list of EQ.TE_LOCO_EQP to answer this question in full, yet I think you'll be able to manage with what I have provided you below. Replace what is in the square brackets ([]) with the field relevant for the join.
I agree with #Snowman in that you could easily research this one.
SELECT
*
FROM
(
SELECT
TRNSP_EQP_EIN
,TRNSP_EQP_ID
,PRE_EQP_ID
,EQP_GRP
,AAR_CT_C
,AAR_MCHDSG_C
,BLD_D
,REBLD_D
FROM
EQ.TE_TRNSP_EQPACTV A
WHERE
TRNSP_EQP_ID = ‘BNSF0000000123’
UNION
SELECT
TRNSP_EQP_EIN
,TRNSP_EQP_ID
,PRE_EQP_ID
,EQP_GRP
,AAR_CT_C
,AAR_MCHDSG_C
,BLD_D
,REBLD_D
FROM
EQ.TE_TRNSP_EQPHIST B
WHERE
A.TRNSP_EQP_ID = ‘ABC0123’
ORDER BY
TRNSP_EQP_EFF_TS
WITH UR /* No idea what this is? */
) X
LEFT JOIN
EQ.TE_LOCO_EQP Y
ON
X.[PRIMARY_KEY] = Y.[EQUIVELANT_FOREIGN_KEY]

Oracle Package or function ... is in an invalid state

I stuck with Oracle store procedure calling. The code looks simple, but I seriously don't know how to make it work.
This is my code for creating the procedure
DELIMITER ##
CREATE OR REPLACE PROCEDURE updateAward(_total_amount in Number, _no_of_sales in Number, _agent in NUMBER, _id in NUMBER) AS
BEGIN
update Award set total_amount = _total_amount, no_of_sales = _no_of_sales, agent_id = _agent where ID = _id ##
commit ##
So, when I execute it through NetBean (it is the only tool I have at this moment), the code run well.
I also tried to run the compile statement
alter PROCEDURE updateAward compile;
and then, use
select *
from user_errors
where name = 'ORG_SPGETTYPE'
The select return empty, proving that the compile process is ok. However, when I trigger the procedure
call updateAward(1,1,1,1);
It returns the error
Package or function UPDATEAWARD is in an invalid state
and the command
SELECT object_name FROM user_objects WHERE status='INVALID';
return the name of the procedure. How can I solve this problem ?
Update 1:
if I use
BEGIN
updateAward(1,1,1,1);
End;
I got error
Error code 6550, SQL state 65000: ORA-06550: line 2, column 20:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
:= . ( % ;
Update 2:
The reason I put the deliminator is because i got error with ";" when working through some vpn to the other network (still not sure why). So, i updated the code like your answer, but then, with the End; in the end of the procedure and then, get the Invalid SQL statement1. If i remove it and execute (through Netbean), the procedure is created successfully. However, after compiling and check the user_errors, it got the
"PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ; "
First things first, your procedure syntax looks wrong. Don't use DELIMITER as that syntax is specific to MySQL. Instead, try something like the following.
CREATE OR REPLACE PROCEDURE updateAward(_total_amount in Number, _no_of_sales in Number, _agent in NUMBER, _id in NUMBER) AS
BEGIN
update Award set total_amount = _total_amount, no_of_sales = _no_of_sales, agent_id = _agent where ID = _id;
commit;
END;
Firstly, there are a couple of things wrong with your procedure:
You're not using delimiters correctly. Delimiters should be used to terminate the whole procedure, not each line.
The NetBeans SQL window doesn't know SQL very well so it cannot tell when the procedure ends and something else begins. Normally, it uses semicolons (;) to tell when one statement ends and another begins, but stored procedures can contain semicolons within them so that wouldn't work. Instead, we change the delimiter to something else so that the NetBeans SQL window sends the entire stored procedure to the database in one go.
Variable names are not allowed to begin with an underscore (_). In particular, rule 5 in the list of Schema Object Naming Rules at this Oracle documentation page states that
Nonquoted identifiers must begin with an alphabetic character from your database character set.
Underscores are not alphabetic characters.
I've taken your procedure, fixed the use of delimiters and added an extra p onto the front of each parameter name (p for 'parameter'), and I got the following, which ran successfully in NetBeans and created a procedure without errors:
delimiter $$
CREATE OR REPLACE PROCEDURE updateAward(p_total_amount in Number, p_no_of_sales in Number, p_agent in NUMBER, p_id in NUMBER) AS
BEGIN
update Award set total_amount = p_total_amount, no_of_sales = p_no_of_sales, agent_id = p_agent where ID = p_id;
commit;
END;
$$
delimiter ;
Secondly, you write
[...] and then, use
select *
from user_errors
where name = 'ORG_SPGETTYPE'
The select return empty, proving that the compile process is ok.
Um, no. This proves that there are no errors in the procedure ORG_SPGETTYPE (or no procedure with that name exists). Your procedure is named updateAward, which Oracle will capitalise to UPDATEAWARD. Try
select *
from user_errors
where name = 'UPDATEAWARD';
instead.

HQL does not ignore values with blank string in column

I am trying to setup a query for my application to pull only values from a table that have a specific column set. Mostly this column will be null, but if you edit and save the item on the application end without putting anything in this field, then it saves a blank string to that database field.
I have tried the TSQL query:
SELECT * from TABLE where COLUMN is not NULL AND COLUMN != ''
This query returns the results I need, but when I run the same query in HQL:
SELECT OBJECT from TABLE where COLUMN is not NULL and COLUMN <> ''
Then it still contains the values that have a blank string in that column. I have tried this using HQL with the operators <> and !=, and have also tried converting it to a criteria object using Restrictions.ne("column","") but nothing seems to provide the result I need.
I tried Length as in the comments, but had no luck. With the length in the query hibernate generates the full query as so. the time_clock_id column is the one that i'm having the problem with. Hibernate is set to SQLServerDialect
select timezone0_.time_zone_id as time1_368_, timezone0_.version as version368_, timezone0_.modification_timestamp as modifica3_368_, timezone0_.time_offset as time4_368_, timezone0_.modification_user as modifica5_368_, timezone0_.name as name368_, timezone0_.description as descript7_368_, timezone0_.active as active368_, timezone0_.time_clock_id as time9_368_ from time_zone timezone0_ where timezone0_.active=1 and (timezone0_.time_clock_id is not null) and len(timezone0_.time_clock_id)>0
Rookie Mistake. There was another place within my action class where I was using a different query to build the select list in the application. This was resulting in the list being overwritten with all values instead of those that use blank. After snipping this duplication I can use the operator column <> '' and I am getting the correct results

How to invertly select columns in sql?

If I have a SQL table with columns:
NR_A, NR_B, NR_C, NR_D, R_A, R_B, R_C
and on runtime, I add columns following the column's sequence such that the next column above would be R_D followed by R_E.
My problem is I need to reset the values of columns that starts with R_ (labeled that way to indicate that it is resettable) back to 0 each time I re-run my script . NR_ columns btw are fixed, so it is simpler to just say something like:
UPDATE table set col = 0 where column name starts with 'NR_'
I know that is not a valid SQL but I think its the best way to state my problem.
Any thoughts?
EDIT: btw, I use postgres (if that would help) and java.
SQL doesn't support dynamically named columns or tables--your options are:
statically define column references
use dynamic SQL to generate & execute the query/queries
Java PreparedStatements do not insulate you from this--they have the same issue, just in Java.
Are you sure you have to add columns during normal operations? Dynamic datamodels are most of the time a realy bad idea. You will see locking and performance problems.
If you need a dynamic datamodel, take a look at key-value storage. PostgreSQL also has the extension hstore, check the contrib.
If you don't have many columns and you don't expect the schema to change, just list them explicitly.
UPDATE table SET NR_A=0;
UPDATE table SET NR_B=0;
UPDATE table SET NR_C=0;
UPDATE table SET NR_D=0;
Otherwise, a simple php script could dynamically build and execute your query:
<?php
$db = pg_connect("host=localhost port=5432 user=postgres password=mypass dbname=mydb");
if(!$db) die("Failed to connect");
$reset_cols = ["A","B","C","D"];
foreach ($col in $reset_cols) {
$sql = "UPDATE my_table SET NR_" . $col . "=0";
pg_query($db,$sql);
}
?>
You could also lookup table's columns in Postgresql by querying the information schema columns tables, but you'll likely need to write a plpgsql function to loop over the query results (one row per table column starting with "NR_").
if you rather using sql query script, you should try to get the all column based on given tablename.
maybe you could try this query to get all column based on given tablename to use in your query.
SELECT attname FROM
pg_attribute, pg_type
WHERE typname = 'tablename' --your table name
AND attrelid = typrelid
AND attname NOT IN ('cmin', 'cmax', 'ctid', 'oid', 'tableoid', 'xmin', 'xmax')
--note that this attname is sys column
the query would return all column with given tablename except system column

Categories