My code is looking like this:
addToTable2(ObjectDTO objectDTO) {
def sql = sql.execute(
"""INSERT INTO SCHEMA.TABLE2 (
COLUMN1,
COLUMN2,
COLUMN3 )
VALUES (
${objectDTO.property1}
${objectDTO.property2}
${objectDTO.property3})""")
}
ArrayList<ObjectDTO> fetchValuesFromTable1() throws CollectionsException {
ArrayList<ObjectDTO> fetchValues= new ArrayList<ObjectDTO>()
def sql = """
SELECT *
FROM SCHEMA.TABLE1
ORDER BY DATE DESC FETCH FIRST 1 ROW ONLY"""
try {
if(this.sql != null) {
this.sql.eachRow(sql) {
resultSet ->
ObjectDTO objectDTO = new ObjectDTO()
objectDTO.setProperty1(resultSet.PROPERTY1)
objectDTO.setProperty2(resultSet.PROPERTY2)
objectDTO.setPropety3(resultSet.PROPERTY3)
objectList.add(poulSifr)
}
}
for(ObjectDTO objectDTO: objectList) {
addToTable2(objectDTO)
}
} catch (SQLException se) {
log.info "fetchValues error $se.message executed sql: $sql"
throw new CollectionsException("fetchValues message $se.message")
} finally {
if (this.sql != null) {
this.sql.close()
}
}
objectList
}
I got this error/warning:
WARN groovy.sql.Sql - Failed to execute: INSERT INTO SCHEMA.TABLE (
COLUMN1,
COLUMN2,
COLUMN3 )
VALUES (
?,
?,
null)
because: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=?;AT
YEAR YEARS MONTH MONTHS DAY DAYS HOUR HOURS MINUTE MINUTES,
DRIVER=3.64.82
Whenever I fetch last value from Table1 I need to put that in Table2. I don't know is this proper way to do it or I'm doing something completely wrong.
you have missing commas in VALUES(...) part of insert
I'm trying to change this function into an SQL query (using Room). The goal is to return a list of items with no duplicates.
A duplicate is defined by either the item.id or any combination of linked ids being present.
fun removeDuplicates(items: List<Table>?) : List<Table>?{
val returnItems = ArrayList<Table>()
items?.distinctBy { _item ->
_item.id
}?.forEach { item ->
val LID1 = item.linked_id_1
val LID2 = item.linked_id_2
val isFoundReturnItem = returnItems.firstOrNull {
(it.linked_id_1 == LID2 && it.linked_id_2 == LID1) ||
(it.linked_id_1 == LID1 && it.linked_id_2 == LID2)
}
//only add to our new list if not already present
if(isFoundReturnItem == null)
returnItems.add(item)
}
return returnItems
}
If I read your question right here is the answer for Microsoft SQL. Structure:
Select Distinct Field1, Field2, ...
From Table
Where Field1 between 'a' and 'm'
Your Script: The distinct command makes distinct rows.
Select Distinct Item
From YourTableName
You can also use GROUP BY this allows aggregations on distinct values
Select Field1, Field2 = max(Field2), ...
From Table
Where Field1 between 'a' and 'm'
Group by Field1
My sql statement is simple as below:
if not exists (select col_a from t_a where co_b = 'v_b')
begin
insert into t_a (col_a ,col_b )
VALUES(v_a,v_b)
end
else
begin
update t_a set col_a = v_a, col_b = v_b where col_b = 'v_b'
end
As I have hundreds of rows to update, how can I do this in Perl for the least time cost?
If I use Prepare + Execute, how to write the statement using the placeholder ? ?
Does the $dbh->prepare($statement); support multiple composite SQL lines like those above? Or do I have to save the lines into an sql file and run it using SQL server?
To make the question more clear, my Perl lines look like those below:
$statement = "if ... VALUES(?,?)...update t_a set col_a = ?, col_b = ?";
# better to use one binding values(v_a, v_b) couplets mapping
# the 2 placeholders of insert and update both?
foreach (#$va_arr) {
my $values_for_one_row = $_;
$dbh->prepare($statement);
$execute->execute($values_for_one_row->{col_a }, $values_for_one_row->{col_b });
}
I forgot one thing: the 'whatever' is also a value in $va_arr to be changed on every iteration: if not exists (select col_a from t_a where co_b = 'v_b'). Also, the update section should be: update t_a set col_a = ?, col_b = ? where col_b = "v_b". Seems no better way then include the prepare into the loop? Sorry I didn't think the example complete. But I think simbabque's answer is good enough.
You can use your SQL without problems. You need to prepare the statement once. I am assuming your $va_arr looks like this:
my $va_arr = [
{
col_a => 1,
col_b => 2,
},
{
col_a => 'foo',
col_b => 'bar',
},
];
Your code to run this could be as follows. Note that you have to pass the col_n params twice as it needs to fill them in two times into each ? with every execute. They get filled in the order of the ? in the query, so we need col_a, col_b for the INSERT and another col_a, col_b for the UPDATE.
my $sql = <<'EOSQL';
if not exists (select col_a from t_a where co_b = 'whatever')
begin
insert into t_a (col_a ,col_b )
VALUES(?, ?)
end
else
begin
update t_a set col_a = ?, col_b = ?
end
EOSQL
my $sth = $dbi->prepare($sql);
foreach ($values = #{ $va_arr }) {
$dbh->execute($values->{col_a }, $values->{col_b },
$values->{col_a }, $values->{col_b });
}
If you have a long list of columns and you know the order, consider this:
my #columns = qw( col_a col_b col_c col_n );
my $va_arr = [
{
col_a => 1,
col_b => 2,
col_n => 99,
},
{
col_a => 'foo',
col_b => 'bar',
col_n => 'baz',
},
];
# build the sql dynamically based on columns
my $sql = q{
if not exists (select col_a from t_a where co_b = 'whatever')
begin
insert into t_a (} . join(',' #columns) . q{)
VALUES(} . join(',', map '?', #columns) . q{)
end
else
begin
update t_a set } . join(',' map { "$_ => ?" } #columns) . q{
end
};
my $sth = $dbi->prepare($sql);
foreach ($values = #{ $va_arr }) {
$dbh->execute(#{$values}{#columns}, #{$values}{#columns});
}
Let's look at what this does. It's helpful if you have a really long list of columns.
You know their names and order, and put that into #columns.
Build the SQL based on these columns. We have to add the column name and a ? to the INSERT and the combination of both to the UPDATE for each of the columns.
Execute it with a hash ref slice
Please note that I have not run this, just hacked it in here.
you should put the prepare statement out of the loop and use a transaction
for example:
my $sql1 = qq(select col_a from t_a where col_b = ?);
my $sql2 = qq(insert into t_a (col_a, col_b) VALUES(?, ?));
my $sql3 = qq(update t_a set col_a = ? where col_b = ?);
my $query = $dbh->prepare($sql1);
$dbh->begin_work();
foreach (#$va_arr) {
my $values_for_one_row = $_;
$query->execute($values_for_one_row->{col_b});
my #out = $query->fetchrow_array();
$query->finish();
if ( not defined $out[0] )
{
$dbh->do($sql2, undef, $values_for_one_row->{col_a}, $values_for_one_row->{col_b});
}
else
{
$dbh->do($sql3, undef, $values_for_one_row->{col_a}, $values_for_one_row->{col_b});
}
}
$dbh->commit();
If upsert is not available, here's how I might do it:
Bulk load the data into a staging table.
Delete all data that joins to the target table.
Insert data from staging to target.
Alternatively you can update from staging to target, delete from the staging data that joins, then insert what's left in staging.
Or, a few hundred rows is not that many, so I might: prepare an insert and an update statement handle outside of the loop. Then in the loop:
my $rows = $upd_sth->execute(...);
$ins_sth->execute(...) if $rows == 0;
I have one table log:
checktype
---------
I
O
I
o
I
I
I
o
I
O
Now I want that I and O should be in a pair so I want to delete the extra I, means I want only one (I or O) after each other.
The table should contain only I and O in pairs.
You can get this result with the following query quite easily.
Select checktype,((ROW_NUMBER() OVER (ORDER BY checktype))*2 - 1) as Row_id From Table
Where checktype = 'I'
UNION
Select checktype,((ROW_NUMBER() OVER (ORDER BY checktype))*2 ) as Row_id From Table
Where checktype = 'O'
Order by Row_id
I have tested it and it is working for me
Try this:
ResultSet rs = stmt.executeQuery("SELECT checkType FROM myTable");
while(rs.next( )){
if (rs.getString("checkType").equals('I'){
if(rs.next(){
if(rs.getString("checkType").equals('O'){
}else{
//delete logic
}
}
} else if(rs.getString("checkType").equals('O'){
if(rs.next(){
if(rs.getString("checkType").equals('I'){
}else{
//delete logic
}
}
}
}
I want to get the value of the last ID insert in a table. How I can do this?
Well the solution that I use is:
select id from NEW TABLE (insert into (val1, val2, ...) values ('lorem', 'ipsum', ...))
This gets the id column from the last row inserted in the DB :)
SELECT IDENTITY_VAL_LOCAL() AS VAL FROM SYSIBM.SYSDUMMY1
See docs.
Have a look at this answer.
http://www.sitepoint.com/php-database-db2/
// get the last inserted ID into the specified table
// int lastInsertID(string $tblName)
function lastInsertID($tblName)
{
if ($this->transIsOpen())
{
$sql = "SELECT SYSIBM.IDENTITY_VAL_LOCAL() AS id FROM " . $tblName;
$rs = $this->query($sql);
return $this->fetch($rs, "id");
}
return -1;
}
OR this
http://www.php.net/manual/en/function.db2-last-insert-id.php#98361
int keyId = -1;
preparedStatement.executeUpdate();
resultSet = preparedStatement.getGeneratedKeys();
if (resultSet.next()) {
keyId = rs.getInt(1);
}
https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#getGeneratedKeys()
Update: and don't forget to create preparedStatement with the following flag Statement.RETURN_GENERATED_KEYS otherwise it won't work)))