GetString of Composite Type Postgres? - java

I created this table:
CREATE TABLE public.luogo
(
id_luogo integer NOT NULL DEFAULT nextval('luogo_id_luogo_seq'::regclass),
tipo character varying(30) NOT NULL,
indirizzo indirizzo,
CONSTRAINT luogo_pk PRIMARY KEY (id_luogo)
)
where indirizzo type is
CREATE TYPE public.indirizzo AS
(
citta character varying(50),
via character varying(50),
cap integer,
civico integer
);
So I'm using JDBC and I need this query
"SELECT * FROM luogo WHERE id_luogo= '"+variable+"'";
The problem is that resultset.getstring("indirizzo") returns obviously a string like: "(value,value,value)". How to get as string the singular parameters of indirizzo?

The correct SQL syntax is:
"SELECT id_luogo,(indirizzo).citta FROM luogo"
To get the String in Java is: resultset.getString("citta")

Related

Bulk Import Derby error SYSCS_IMPORT_DATA CHARACTERDELIMITER must be CHAR(1)

Hi I trying to import txt values file into derby database using CALL SYSCS_UTIL.SYSCS_IMPORT_DATA.
Each value column is delimited by ; and the line of values is delimited by LF Line Feed.
111142501;283811110;01111000;28111004;EXPO[LF]
In my java method I'm invoking SYSCS_IMPORT_DATA like this
String driver = "org.apache.derby.jdbc.EmbeddedDriver";
String protocol = "jdbc:derby:";
Connection conexion = null;
File bd = new File(configProperties.getDdbbDir());
String absolutePathDB = bd.getAbsolutePath();
Class.forName(driver).newInstance();
Properties props = new Properties();
conexion = DriverManager.getConnection(protocol + absolutePathDB, props);
conexion.setAutoCommit(false);
Statement s = conexion.createStatement();
String queryCer = "CALL SYSCS_UTIL.SYSCS_IMPORT_DATA('ROOT','ELECTOR','COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5',null,'" + + StringUtils.replace(file.getAbsolutePath(), "\\", "\\\\") + "',';', '\\n', 'UTF-8', 0)";
s.execute(queryCer);
When my applications goes by statement execute finishes with the following error:
Caused by: ERROR 22001: A truncation error was encountered trying to shrink CHAR '\n' to length 1.
I've tried to change CHARACTERDELIMITER for other values , like ", ' or null, but other errors appears. Also I've tried to import the lines enclosed by "", but does not working.
As Christoph adviced me, I've changed the invocation replacing '\n' by null (the column names are in Spanish)
CALL SYSCS_UTIL.SYSCS_IMPORT_DATA('ROOT','ELECTOR','CODIGO_CENSO, CODIGO_PROVINCIA, NOMBRE_PROVINCIA, CODIGO_MUNICIPIO, NOMBRE_MUNICIPIO, CODIGO_DISTRITO,
CODIGO_SECCION, CODIGO_SUB_SECCION, MESA, NUMERO_ORDEN, IDENTIFICADOR, PRIMER_APELLIDO_NORMALIZADO,
SEGUNDO_APELLIDO_NORMALIZADO, NOMBRE_NORMALIZADO, FECHA_NACIMIENTO, INDICADOR_CORREO, SEXO, GRADO_ESC,
PRIMER_APELLIDO_SIN_NORMALIZAR, SEGUNDO_APELLIDO_SIN_NORMALIZAR, NOMBRE_SIN_NORMALIZAR, CODIGO_CIERRE, NIE, EATIM, JUNTA_ZONA, PERIODO'
,'7,17,54,12,51,9,20,21,47,56,39,63,67,52,36,40,69,37,64,68,55,8,49,33,43,60',
'fichero.csv',';', null, 'UTF-8', 0)
but now I have the following error: java.sql.SQLException: The exception 'java.sql.SQLSyntaxErrorException: Column 'COLUMNXX' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'COLUMN54' is not a column in the target table.' was thrown while evaluating an expression.
As you can see, I've included the index of column to import data values, because if it wasn't indicated the error was the following:
Caused by: java.sql.SQLException: The column ID in table ELECTOR does not allow null values.
So, I have to put the index columns.
Here one register from csv file:
1;28;MADRID ;903;XXXX XXXXXX ;01;022 ; ;B;00000466;*****7***;SOMBRERO ;ROZAS ;PEPITO ;200X0404; ;V;3;PISCINAS ;ROZAS ;PEPITO ;000042501;288000000;00000000;20000000;EXPO
Y la data table has the following column names:
('ID','APELLIDO_CASADA','BLOQUE','CALIFICADOR','CIAY','CIUDAD','CODIGO_CENSO','CODIGO_CIERRE','CODIGO_DISTRITO',
'CODIGOEC','CODIGOES','CODIGO_MUNICIPIO','CODIGO_MUNICIPIO_NACIMIENTO','CODIGO_NUCLEO','CODIGO_PAIS',
'CODIGO_POSTAL','CODIGO_PROVINCIA','CODIGO_PROVINCIA_NACIMIENTO','CODIGO_PSEUDOVIA','CODIGO_SECCION',
'CODIGO_SUB_SECCION','CODIGO_TIPO_VIA','CODIGO_VIA','CONSULADO','DESCRIPCIONEC','DESCRIPCIONES','DESCRIPCION_NUCLEO',
'DESCRIPCION_PSEUDOVIA','DESCRIPCION_TIPO_VIA','DESCRIPCION_VIA','DIGITO_CONTROL_NIE','DIRECCION_POSTAL',
'EATIM','ESCALERA','FECHA_CARGA','FECHA_NACIMIENTO','GRADO_ESC','HM','IDENTIFICADOR','INDICADOR_CORREO',
'INDICADOR_INHABILITADO','IVOTO','JUNTA_ZONA','KM','LETRA_DNI','LETRA_EXTRANJERO','MESA','MUNICIPIO_CERA',
'NIE','NOMBRE_CONSULADO','NOMBRE_MUNICIPIO','NOMBRE_NORMALIZADO','NOMBRE_PAIS_CERA','NOMBRE_PROVINCIA',
'NOMBRE_SIN_NORMALIZAR','NUMERO_ORDEN','NUMERO_VIA','PAIS_CERA','PAIS_NACION','PERIODO','PISO','PORTAL',
'PRIMER_APELLIDO_NORMALIZADO','PRIMER_APELLIDO_SIN_NORMALIZAR','PROVINCIA_CERA','PUERTA','SEGUNDO_APELLIDO_NORMALIZADO',
'SEGUNDO_APELLIDO_SIN_NORMALIZAR', 'SEXO', 'TIPO_IDENTIFICADOR')
Any help will be appreciate.
Thanks
Regards,
Jose Pascual
The syntax of the stored procedure according to documentation is
SYSCS_UTIL.SYSCS_IMPORT_DATA (IN SCHEMANAME VARCHAR(128),
IN TABLENAME VARCHAR(128), IN INSERTCOLUMNS VARCHAR(32672),
IN COLUMNINDEXES VARCHAR(32672), IN FILENAME VARCHAR(32672),
IN COLUMNDELIMITER CHAR(1), IN CHARACTERDELIMITER CHAR(1),
IN CODESET VARCHAR(128), IN REPLACE SMALLINT)
Assuming the file's name is 'C:\import.csv', String queryCer resolves to
CALL SYSCS_UTIL.SYSCS_IMPORT_DATA('ROOT',
'ELECTOR','COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5',
null,'C:\import.csv',
';', '\n', 'UTF-8', 0)
where ";" being the column delimiter (which is correct) and "\n" being the character delimiter, which is incorrect as there is no character delimiter. So,replace '\\n' by null (without quotes).

Inserting a table with two key values

I´m using Postgres and java to write files out of a .csv into a db. In my CREATE TABLE stmnts, I have a table which stores two keys. These I want to insert. I now have a subquery but i always get a null value for the ckey, so the syntax must be wrong. The INSERT does not work. ERROR: null value in column "ckey" of relation "gamesin" violates not-null constraint. The other value I get out of a list I created. I´m using a prepared statement. Help appreciated!
CREATE TABLE Games(
Year INT PRIMARY KEY,
Name VARCHAR(32) NOT NULL,
StartDate Date NOT NULL,
EndDate Date NOT NULL
);
CREATE TABLE Cities(
CKey SERIAL PRIMARY KEY,
Name VARCHAR(128) UNIQUE NOT NULL,
Noc CHAR(3) REFERENCES Countries NOT NULL
);
CREATE TABLE GamesIn(
Year INT REFERENCES Games,
CKey INT REFERENCES Cities,
PRIMARY KEY(Year, CKey)
);
String sql = "INSERT INTO gamesin (year, ckey) VALUES (?, (SELECT ckey from cities WHERE cities.name = '\" + name + \"'))";

Inserting Data into DB ERROR: Columns of type 'VARCHAR' cannot hold values of type 'INTEGER'

I have built a DB, and now I'm writing a function which inserts data into that DB.
I guess the problem is something I don't see, the error I get is:
Columns of type 'VARCHAR' cannot hold values of type 'INTEGER'.
while I completely understand what that means I just can't get it to work.
here is my code for insertion:
public static void insertIntoCouponsDB(long COMPANY_ID, String TITLE, String START_DATE, String END_DATE, int AMOUNT, String TYPE, String MESSAGE, double PRICE, String IMAGE) throws SQLException {
Connection connection = DriverManager.getConnection(connectionString);
String sql = String.format("insert into Coupons (COMPANY_ID, TITLE, START_DATE,END_DATE,AMOUNT,TYPE,MESSAGE,PRICE,IMAGE) values (%d, '%s', '%s','%s',%d,'%s','%s',%.2f,'%s')",COMPANY_ID,TITLE,START_DATE,END_DATE,AMOUNT,TYPE,MESSAGE,PRICE,IMAGE);
PreparedStatement preparedStatement = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
preparedStatement.executeUpdate();
ResultSet resultSet = preparedStatement.getGeneratedKeys();
resultSet.next();
int id = resultSet.getInt(1);
System.out.println("Insertion into Coupons DONE !!! New ID: " + id);
}
}
and this is the code for the tabke creation:
public static void buildCouponsDB() {
try {
Connection connection = DriverManager.getConnection(connectionString);
Statement statement = connection.createStatement();
String sql = "create table Coupons (" +
"ID bigint not null primary key " +
"generated always as identity(start with 1, increment by 1), "+
"COMPANY_ID bigint not null, "+
"TITLE varchar(50) not null, "+
"START_DATE date not null, "+
"END_DATE date not null, "+
"AMOUNT integer not null, "+
"TYPE varchar(50) not null, "+
"MESSAGE varchar(250) not null, "+
"PRICE double not null, "+
"IMAGE varchar(100) not null)";
statement.executeUpdate(sql);
System.out.println("Coupons Table has been Created Succesfully !!");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
can anybody help?
I am a begginer so sorry if its to easy of a question, but still, asking for help. Thanks in Advance.
Seems like DerbyDB does not support implicit conversion from integers to varchar datatype, like many (most?) other databases do.
A quick review of the documentation did not give any information about the implicit conversions.
There is CAST function CAST ( [ expression | NULL | ? ] AS dataType ), but from the table in the documentation it appears that the conversion from all numeric datatypes (SMALLINT, INTEGER, BIGINT, DECIMAL etc) is not supported.
Luckily thete is another [CHAR(https://db.apache.org/derby/docs/10.14/ref/rrefbuiltchar.html) function, and it seems that this function can be used to convert numeric values to varchar datatye:
Integer to character syntax
CHAR ( integerExpression )
integerExpression
An expression that returns a value that is an
integer data type (either SMALLINT, INTEGER, or BIGINT). The result is
the character string representation of the argument in the form of an
SQL integer constant. The result consists of n characters that are the
significant digits that represent the value of the argument with a
preceding minus sign if the argument is negative. The result is left
justified.
If the first argument is a SMALLINT: The length of the result is 6. If
the number of characters in the result is less than 6, then the result
is padded on the right with blanks to length 6.
If the first argument
is an INTEGER: The length of the result is 11. If the number of
characters in the result is less than 11, then the result is padded on
the right with blanks to length 11.
If the first argument is a BIGINT:
The length of the result is 20. If the number of characters in the
result is less than 20, then the result is padded on the right with
blanks to length 20.
So you must use CHAR fuction to convert numerics to VARCHAR datatype.
A quick test I've done using ij derby client showed that the above is true:
ij> connect 'jdbc:derby://localhost:1527/myDB;create=true'
> ;
ij> create table x( x integer, y varchar(20) );
0 wierszy wstawionych/zaktualizowanych/usuniŕtych
ij> insert into x values( 1,1);
BúąD 42821: Kolumny typu 'VARCHAR' nie mog╣ przechowywaŠ wartoťci typu 'INTEGER'.
ij> insert into x values( 1, cast(1 as varchar));
BúąD 42X01: B│╣d sk│adniowy: Encountered ")" at line 1, column 43.
Issue the 'help' command for general information on IJ command syntax.
Any unrecognized commands are treated as potential SQL commands and executed directly.
Consult your DBMS server reference documentation for details of the SQL syntax supported by your server.
ij> insert into x values( 1, char(1));
1 wiersz wstawiony/zaktualizowany/usuniŕty
ij> commit;
ij> select * from x;
X |Y
--------------------------------
1 |1
1 wiersz wybrany
ij>
EDIT
It seems that CAST( 1 AS CHAR ) also works, I've done a test:
ij> insert into x values( 1, cast(1 as char));
1 wiersz wstawiony/zaktualizowany/usuniŕty
ij>

Java split string with RegexOption.MULTILINE

I want to split for example the following Sql statements by semi-colon end of line:
CREATE TABLE projects(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX ix_tasks_project_id ON tasks (project_id);
SELECT * FROM projects WHERE name = "someName;WithSemiColon";
Something like:
string.split(";$"); (but with RegexOption.MULTILINE applied)
Can someone please explain how do I apply the RegexOption?
Simply prefix your regular expression with (?m) to enable the flag MULTILINE so in your case it would be (?m);$
for (String s : string.split("(?m);$")) {
System.out.printf("----> %s%n", s.trim());
}
Output:
----> CREATE TABLE projects(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
)
----> CREATE INDEX ix_tasks_project_id ON tasks (project_id)
----> SELECT * FROM projects WHERE name = "someName;WithSemiColon"

Cant insert an empty date value into mysql

String datum = datumInvoer.getText();
**String bdate = bdatumInvoer.getText();**
String[] speler = spelers.getSelectedItem().toString().split(" ");
String[] toernooi = toernooien.getSelectedItem().toString().split(" ");
try {
PreparedStatement query = con.prepareStatement("INSERT INTO `fullhouse`.`inschrijving_toernooi` ( `IT_datum`, `IT_betaaldatum`, `speler`, `toernooi`) VALUES (?, ?, ? ,?)");
query.setString(1, datum);
query.setString(2, bdatum);
query.setString(3, speler[0]);
query.setString(4, toernooi[0]);
query.execute();
i have set the default to NULL , but it still wont insert it i am close to changing the datatype to varchar.
ERROR: incorrect date value
delimiter $$
CREATE TABLE `inschrijving_toernooi` (
`IT_code` int(11) NOT NULL AUTO_INCREMENT,
`IT_datum` date DEFAULT NULL,
`IT_betaaldatum` date DEFAULT NULL,
`speler` int(11) NOT NULL,
`toernooi` int(11) NOT NULL,
PRIMARY KEY (`IT_code`),
UNIQUE KEY `aaa` (`speler`,`toernooi`),
KEY `FS_code_idx` (`speler`),
KEY `FT_code_idx` (`toernooi`),
First Convert your date parameter from string to date. For that follow code below.
String bdate = bdatumInvoer.getText();
// get the correct date Format
// follow the link to get correct date format
// throws ParseException
Date date = new SimpleDateFormat("dd-MM-yyyy").parse(bdate);
Class SimpleDateFormat API
Now in prepared statement set them as date like shown below. As your table structure allows date in table.
query.setDate(2, date);
Now you still want to set null to that column then you can use and tell your query to set null by using following format in prepared statement.
query.setNull(2, java.sql.Types.DATE);
OR
query.setDate(2, null);
setNull API
Mapping of java.sql.Types to SQL types
I think this will solve your issue.
You need to change how you are passing parameters to you prepared statement
It should be something like below. And datum and bdatum should be of type Date. If you do not use what types are defined in your db you could put pass invalid data to your sql which would cause exceptions.
query.setDate(1, datum);
query.setDate(2, bdatum);
query.setInt(3, speler[0]);
query.setInt(4, toernooi[0]);
I suspect your bdatum variable contains an empty string. If you want to insert a SQL null, you need to pass in null, not empty string. (When I tried this on my machine with a similar insert, I got an "Incorrect date value" when trying to insert an empty string, but not with a null.)
if ("".equals(bdatum))
bdatum = null;
ps.setString(2, bdatum);
When you pass in a string in JDBC for a date value, MySQL will try to parse it, but empty string ("") is not a valid value. This works similarly to if you tried to do an insert with a date literal:
INSERT INTO `some_table` (`some_nullable_date_column`) VALUES ('2000-01-01') -- this works
INSERT INTO `some_table` (`some_nullable_date_column`) VALUES (NULL) -- this works
INSERT INTO `some_table` (`some_nullable_date_column`) VALUES ('') -- this fails
As an aside, passing in a string for a date value is semantically wrong and possibly less robust than parsing the string to a Date object before passing it to the PreparedStatement.

Categories