MyBatis iterate list which contains hashmap - mybatis

How would one iterate over a list which contains a map inside.
<foreach item="item" index="index" collection="list">
${item}.{key}
</foreach>
this doesn't seem to work for me

You should use it like this:
<foreach item="item" index="index" collection="list">
${item.key}
</foreach>

Related

Trying upsert and foreach in postgresql mybatis

<insert id="UPSERT" parameterType="ArrayList">
INSERT INTO
table(column1, column2, column3)
VALUES
<foreach item="paramsList" separator="," collection="list">
('${paramsList.column1}', '${paramsList.column2}', '${paramsList.column3}')
</foreach>
ON CONFLICT (column1, column2)
DO UPDATE SET
column3 = values(column3)
</insert>
I was trying to make simple upsert, and the error says
ERROR: syntax error at or near "("
this part > column3 = values(column3)
So I'm assuming that unlike mysql, I can't use values() to re-use values from foreach.
Then which alternative I can use instead?

Extract value from an xmlstring in db2

I have an XML string in a column called RawData from table Inbound. I have to read value Success from an element called status.
xmlstring:
<InboundMessage>
<Transaction>
<Status>Success</Status>
</Transaction>
</InboundMessage>
SELECT X.STATUS
FROM (VALUES XMLPARSE(DOCUMENT '
<InboundMessage>
<Transaction>
<Status>Success</Status>
</Transaction>
</InboundMessage>
')) T (DOC)
, XMLTABLE
(
'$D/InboundMessage/Transaction/Status' PASSING T.DOC AS "D" COLUMNS
STATUS VARCHAR(20) PATH '.'
) X;
Refer to the XMLTABLE function overview link for more details.

Error with PersistenceEnforce when using inherited entity

In my model I have set defaultPersistenceEnforce="true", because I want the database to enforce referential integrity.
However, I get an error when deleting an entity.
Here is my model:
<cf:entity name="Keyword">
<cf:property name="Id" key="true" />
<cf:property name="Value" typeName="string" />
</cf:entity>
<cf:entity name="BaseOrderline" abstract="true">
<cf:property name="Id" key="true" />
</cf:entity>
<cf:entity name="Orderline" baseTypeName="{0}.BaseOrderline">
<cf:property name="Order" typeName="{0}.Order" />
<cf:property name="Keywords" typeName="{0}.KeywordCollection" />
</cf:entity>
<cf:entity name="Order">
<cf:property name="Id" key="true" />
<cf:property name="Keywords" typeName="{0}.KeywordCollection" />
<cf:property name="Orderlines" typeName="{0}.OrderlineCollection" cascadeDelete="Before" cascadeSave="After" />
</cf:entity>
Here is my code:
Keyword keyword = new Keyword();
keyword.Save();
Order order = new Order();
order.Keywords.Add(keyword);
Orderline orderline = new Orderline();
orderline.Keywords.Add(keyword);
order.Orderlines.Add(orderline);
// Save the order and its order lines.
order.Save();
// Delete the order and its order lines.
order.Delete();
I get the following error:
The DELETE statement conflicted with the REFERENCE constraint "FK_Orl_Bas_Bas_Ore". The conflict occurred in table "dbo.Orderline_Keywords_Keyword", column 'BaseOrderline_Id'.
The DELETE statement conflicted with the REFERENCE constraint "FK_Ore_Ord_Ord_Ord". The conflict occurred in table "dbo.Orderline", column 'Orderline_Order_Id'.
Concurrency error in procedure Order_Delete
Everything goes fine if I remove orderline.Keywords.Add(keyword); from the code.
Here is the code of the stored procedure Order_Delete:
USE [PersistenceIdentity]
GO
/****** Object: StoredProcedure [dbo].[Order_Delete] Script Date: 18-7-2016 20:41:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Order_Delete]
(
#Order_Id [uniqueidentifier],
#_rowVersion [rowversion]
)
AS
SET NOCOUNT ON
DECLARE #error int, #rowcount int
DECLARE #tran bit; SELECT #tran = 0
IF ##TRANCOUNT = 0
BEGIN
SELECT #tran = 1
BEGIN TRANSACTION
END
DELETE [Order_Keywords_Keyword] FROM [Order_Keywords_Keyword]
WHERE ([Order_Keywords_Keyword].[Order_Id] = #Order_Id)
SELECT #error = ##ERROR, #rowcount = ##ROWCOUNT
DELETE [BaseOrderline] FROM [BaseOrderline]
INNER JOIN [Orderline] ON ([BaseOrderline].[BaseOrderline_Id] = [Orderline].[BaseOrderline_Id])
LEFT OUTER JOIN [Order] ON ([Orderline].[Orderline_Order_Id] = [Order].[Order_Id])
WHERE ([Order].[Order_Id] = #Order_Id)
SELECT #error = ##ERROR, #rowcount = ##ROWCOUNT
DELETE [Orderline] FROM [Orderline]
LEFT OUTER JOIN [Order] ON ([Orderline].[Orderline_Order_Id] = [Order].[Order_Id])
LEFT OUTER JOIN [Orderline] [Orderline$1] ON ([Order].[Order_Id] = [Orderline$1].[Orderline_Order_Id])
WHERE ([Order].[Order_Id] = #Order_Id)
SELECT #error = ##ERROR, #rowcount = ##ROWCOUNT
DELETE [Order] FROM [Order]
WHERE (([Order].[Order_Id] = #Order_Id) AND ([Order].[_rowVersion] = #_rowVersion))
SELECT #error = ##ERROR, #rowcount = ##ROWCOUNT
IF(#rowcount = 0)
BEGIN
IF #tran = 1 ROLLBACK TRANSACTION
RAISERROR (50001, 16, 1, 'Order_Delete')
RETURN
END
IF #tran = 1 COMMIT TRANSACTION
RETURN
As you can see the following lines are missing in this stored procedure:
DELETE [Orderline_Keywords_Keyword] FROM [Orderline_Keywords_Keyword]
WHERE ([Orderline_Keywords_Keyword].[Orderline_Id] = #Orderline_Id)

Insert multiple records from xml

I want bulk insert into a PostgreSQL database: backend code would create XML like
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
</items>
which I want to pass to a function and save all the values in one go.
But I'm stuck at xpath: each "column" seems to be an array of values, and I'm not sure how to insert them into a table then. Here's a test example:
CREATE TEMP TABLE temp_values (dt date, name varchar, count int);
WITH x AS (SELECT '
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
<i dt="2014-08-03" name="bbd" count="10" />
</items>'::xml AS t
)
INSERT INTO temp_values
SELECT
xpath('/items/i/#dt', t),
xpath('/items/i/#name', t),
xpath('/items/i/#count', t)
FROM x;
Now, in the end I want temp_values to have 3 records, as in the XML, but the table is empty.
If you comment out the "insert into" line, you'd see that the values are parsed correctly. It's just that it returns a single record where each column is an array, instead of returning multiple records.
What am I missing?
Ok, apparently unnest and array indexing is the solution:
unnest(array) | expand an array to a set of rows
So the code would be
CREATE TEMP TABLE temp_values (dt date, name varchar, count int) ON COMMIT DROP;
WITH x AS (SELECT '
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
<i dt="2014-08-03" name="bbd" count="10" />
</items>'::xml AS t
)
INSERT INTO temp_values
SELECT
CAST(CAST((xpath('//#dt', node))[1] as varchar) as date),
CAST((xpath('//#name', node))[1] as varchar),
CAST(CAST((xpath('//#count', node))[1] as varchar) as int)
FROM (SELECT unnest(xpath('/items/i', t)) AS node FROM x) sub;
SELECT * FROM temp_values
I'd prefer to delete some extra slashes before #:
CREATE TEMP TABLE temp_values (dt date, name varchar, count int) ON COMMIT DROP;
WITH x AS (SELECT '
<items>
<i dt="2014-08-01" name="vvv" count="12" />
<i dt="2014-08-02" name="zzz" count="6" />
<i dt="2014-08-03" name="bbd" count="10" />
</items>'::xml AS t
)
INSERT INTO temp_values
SELECT
CAST(CAST((xpath('#dt', node))[1] as varchar) as date),
CAST((xpath('#name', node))[1] as varchar),
CAST(CAST((xpath('#count', node))[1] as varchar) as int)
FROM (SELECT unnest(xpath('/items/i', t)) AS node FROM x) sub;
SELECT * FROM temp_values

Select IN on more than 2100 values

How can you do a select in on more than 2100 values?
<cfquery name="result.qryData">
SELECT sub_acct_no, ...
FROM dbo.Closed_ORDER
WHERE ord_no IN <cfqueryparam cfsqltype="CF_SQL_varchar" value="#ValueList(qryOrd.ord_no)#" list="yes">
</cfquery>
Because of the ways that the tables are setup, linked Servers and JOINS are not an option.
When this is ran an error this thrown because there are new many fields being passed in.
First load the values into XML
<cfset var strResult = '<ul class="xoxo">'>
<cfloop query="qryOrd">
<cfset strResult &= '<li>#xmlformat(ord_no)#</li>'>
</cfloop>
<cfset strResult &= '</ul>'>
Then use the xml in the sql query
<cfquery name="result.qryData">
DECLARE #xmlOrd_no xml = <cfqueryparam cfsqltype="CF_SQL_varchar" value="#strResult#">
DECLARE #tblOrd_no TABLE (ID varchar(20))
INSERT INTO #tblOrd_no
SELECT tbl.Col.value('.', 'varchar(20)')
FROM #xmlOrd_no.nodes('/ul/li') tbl(Col)
SELECT sub_acct_no, ...
FROM dbo.Closed_ORDER
WHERE ord_no IN (SELECT ID FROM #tblOrd_no)
</cfquery>
You can also do a dump of the XML and it is properly formatted in HTML
<cfoutput>#strResult#</cfoutput>