I'm trying to create an simple SQL TDE template for XML documents in Marklogic DB.
Sample template:
<template xmlns="http://marklogic.com/xdmp/tde">
<context>/match</context>
<collections>
<collection>source1</collection>
</collections>
<rows>
<row>
<schema-name>soccer</schema-name>
<view-name>matches</view-name>
<columns>
<column>
<name>id</name>
<scalar-type>long</scalar-type>
<val>id</val>
</column>
<column>
<name>document</name>
<scalar-type>string</scalar-type>
<val>docUri</val>
</column>
<column>
<name>date</name>
<scalar-type>date</scalar-type>
<val>match-date</val>
</column>
<column>
<name>league</name>
<scalar-type>string</scalar-type>
<val>league</val>
</column>
</columns>
</row>
</rows>
</template>
I have inserted a sample document in the content database and the above template into Schemas database.
Now I'm trying to run a SQL query using XQuery as below:
xdmp:sql("select * from matches","map")
The above query returns the below response
soccer.matches.id
soccer.matches.document
soccer.matches.date
soccer.matches.league
1234567
/soccer/match/1234567.xml
2016-01-12
Premier
In json format it is,
[
{
"soccer.matches.id": 1234567,
"soccer.matches.document": "/soccer/match/1234567.xml",
"soccer.matches.date": "2016-01-12",
"soccer.matches.league": "Premier"
}
]
In the above response the key name is returned as schema-name.view-name.column_name.E.g.,soccer.matches.id
But I need the key name to have only the column name.E.g., "id": 1234567
Could anyone please share the easiest way to achieve this in XQuery?
You could probably se the names in the SQL statement using AS. You could always iterate over thr the results in a FLWOR statement to modify your results.
However, I suggest that you use the optic API and tune the results as you wish.
Using an op:from-view would be the suggested course of action. You could still use op:from-sql(). In both cases, experiment with the qualifier parameter including omitting it . For the final results, you can use an op:as() with op:select() or op:group-by() to define exactly what you want.
Optic API reference: https://docs.marklogic.com/guide/app-dev/OpticAPI
Optic Functions:
https://docs.marklogic.com/op
Related
Working with liquibase I've found that it's possible to define properties, and use them as defaultValue for columns.
Everything is ok if you use pre-made functions, but how to do when you have some custom SQL that produces some data, to be used in the same manner?
I tried to do something like this:
<property name="myFunc" value="SELECT CURRENT_DATE + time '08:00:00' + (random() * interval '3 hours')::time" dbms="postgresql"/>
...
<column name="selected_pickup_date" type="datetime" defaultValueComputed="${myFunc}" remarks="Selected from customer during order creation">
<constraints nullable="false"/>
</column>
But it didn't work! The error code showed that liquibase was just placing my SQL string as the column's default value.
SQL wasn't parsed as I expected.
How to proceed to get the query result used as default value?
After many attempts, I understood that Liquibase doesn't parse SQL in properties, probably it only executes functions and places their result in the property value, and the placeholder ${xxx} is replaced with the function's output.
Once a new row is added to the table, and the column with defaultValue is empty, the property value is read and used in place of NULL.
I tried many solutions and luckily the last one worked:
Take the SQL and create a new function in a sql file, in my case it was simple:
DROP FUNCTION IF EXISTS fixed_date_rand_time;
CREATE FUNCTION fixed_date_rand_time() RETURNS timestamp
AS $$ SELECT CURRENT_DATE + time '08:00:00' + (random() * interval '3 hours')::time $$
LANGUAGE SQL;
Import the sql before other changelogs
<include relativeToChangelogFile="true" file="func.sql" />
Now..you can create the property! This time calling the function instead of the SQL string
<property name="myFunc" value="fixed_date_rand_time()" dbms="postgresql"/>
...
<changeSet id="20201026174848-1" author="jhipster">
<createTable tableName="my_table">
<column name="selected_pickup_date" type="datetime" defaultValueComputed="${myFunc}" remarks="Selected from customer during order creation">
<constraints nullable="true"/>
</column>
</createTable>
</changeSet>
...
Et Voilà! It works now!
The very-nice thing is that properties can be used with context too, allowing you to bypass the new function when outside of local test environment:
<property name="myFunc" value="fixed_date_rand_time()" dbms="postgresql" context="test"/>
<property name="myFunc" value="NULL" dbms="postgresql" context="!test"/>
Not perfect, it works only with nullable columns, but there must a solution.
Finally the database is loaded with correct values automatically, taking away the hassle of updating dates everyday, to have everything work as expected.
I hope that this solution can help somebody, who maybe has the will to refine it a bit :-)
My Liquibase version is 3.10, I cannot update to the latest due to other dependencies... maybe the problem has been addressed there.
I don't exclude that the feature has been disabled intentionally in favour of the pro version.
Have a nice day
My administrative program uses an xml-file to import pricelists (txt files) to the SQL database.
There is a lot of rows in the XML file but this is the rows I have problems with.
<?xml version="1.0"?>
<BCPFORMAT>
<RECORD>
<FIELD ID="41" xsi:type="CharFixed" LENGTH="5" COLLATION=""/>
</RECORD>
<ROW>
<COLUMN SOURCE="41" NAME="VGRNR1" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="41" NAME="VGRNR2" xsi:type="SQLVARYCHAR"/>
</ROW>
</BCPFORMAT>
I have changed the eighth row to COLUMN SOURCE="41" because I want the data from FIELD ID="41" in both fields VGRNR1 and VGRNR2 in the SQL database.
When I make the change I get this error message from my administrative program:
duplicate element id "41"
Is it possible to edit the xml-file so I can get data from FIELD ID="41" in both fields VGRNR1 and VGRNR2 in the database?
I'm working with SQL data hosted by a 3rd party, and am trying to pull some specific information for reporting. However, some of what I need to parse out is in XML format, and I'm getting stuck. I'm looking for the syntax to pull the text= values only from the XML code.
I believe the code should something like this, but most of the examples I can find online involve simpler XML hierarchy's than what I'm dealing with.
<[columnnameXML].value('(/RelatedValueListBO/Items/RelatedValueListBOItem/text())[1]','varchar(max)')>
Fails to pull any results. I've tried declaring the spacenames as well, but again...I only ever end up with NULL values pulled.
Example XML I'm dealing with:
<RelatedValueListBO xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://tempuri.org/RelatedValueListBOSchema.xsd">
<Items>
<RelatedValueListBOItem groupKey="Response1" text="Response1" selected="true" />
<RelatedValueListBOItem groupKey="Response2" text="Response2" selected="true" />
<RelatedValueListBOItem groupKey="Response3" text="Response3" selected="true" />
</Items>
</RelatedValueListBO>
Ideally I'd like to pull response1; response2; response3 into a single column. Allowing for the fact that multiple responses may exist. I believe I'm getting stuck with the basic code I've been trying due to the namespaces associated to RelatedValueListBO and the fact that what I want is grouped in groupKey, text, and selected, instead of the value I want just being under the Items node.
You have the namespaces defined in your XML, so you need to define them in the XQuery too.
Fast and dirty method is to replace all namespaces with a "*":
SELECT #x.value('(/*:RelatedValueListBO/*:Items/*:RelatedValueListBOItem/#text)[1]','varchar(max)')
To get all responses in a single column you can use:
SELECT
Item.Col.value('./#text','varchar(max)') X
FROM #x.nodes('/*:RelatedValueListBO/*:Items/*:RelatedValueListBOItem') AS Item(Col)
If you need a better performance, you may need to define namespaces properly.
You can use something like this to extract the value of "text" in the first node of RelatedValueListBOItem
SELECT extractvalue(value(rs), '//RelatedValueListBOItem[1]/#text')
FROM TABLE (xmlsequence(extract(sys.xmltype('<RelatedValueListBO>
<Items>
<RelatedValueListBOItem groupKey="Response1" text="Response1"
selected="true" />
<RelatedValueListBOItem groupKey="Response2" text="Response2"
selected="true" />
<RelatedValueListBOItem groupKey="Response3" text="Response3"
selected="true" />
</Items>
</RelatedValueListBO>'),'/RelatedValueListBO/Items'))) rs;
I'm running into the below error
Mapping Failed. Cannot Import Column: RECIPIENT_ID Unable to continue
I’m using API method (snippet below), and
<Envelope>
<Body>
<ImportList><MAP_FILE>ODS_To_Silverpop_Mapping.XML</MAP_FILE>
<SOURCE_FILE>ODS_To_Silverpop_20170123171113.TXT</SOURCE_FILE></ImportList>
</Body>
</Envelope>
and passing the XML file for mapping information (snippet below), along with the raw data file (not attached here). As per the API documentation, I'm saving these two files in the silverpop FTP folder and making the API call. This code is working if I don't use the 'RECIPIENT_ID' (which is the auto generated hidden system field) in the mapping xml file (in columns mapping list and in the sync fields list), and use some other key to sync. However, in this specific case, I need too use the RECIPIENT_ID as there is no other reliable field. Does any one have experience with the Silverpop ImportList API method? and thoughts about this issue?
<?xml version="1.0" encoding="UTF-8"?>
<LIST_IMPORT>
<LIST_INFO>
<ACTION>ADD_AND_UPDATE</ACTION>
<LIST_ID>23232323</LIST_ID>
<FILE_TYPE>0</FILE_TYPE>
<HASHEADERS>true</HASHEADERS>
</LIST_INFO>
<SYNC_FIELDS>
<SYNC_FIELD>
<NAME>RECIPIENT_ID</NAME>
</SYNC_FIELD>
</SYNC_FIELDS>
<MAPPING>
<COLUMN>
<INDEX>1</INDEX>
<NAME>Email</NAME>
<INCLUDE>true</INCLUDE>
</COLUMN>
<COLUMN>
<INDEX>2</INDEX>
<NAME>RECIPIENT_ID</NAME>
<INCLUDE>true</INCLUDE>
</COLUMN>
<COLUMN>
<INDEX>3</INDEX>
<NAME>FirstName</NAME>
<INCLUDE>true</INCLUDE>
</COLUMN>
<COLUMN>
<INDEX>4</INDEX>
<NAME>LastName</NAME>
<INCLUDE>true</INCLUDE>
</COLUMN>
<INDEX>5</INDEX>
<NAME>Last Modified Date</NAME>
<INCLUDE>false</INCLUDE>
</COLUMN>
</MAPPING>
</LIST_IMPORT>
Yes In your mapping XML file please Add
<USE_RECIPIENT_ID>true</USE_RECIPIENT_ID> inside list_info
below is the snippet
<LIST_INFO>
<ACTION>ADD_AND_UPDATE</ACTION>
<LIST_ID>23232323</LIST_ID>
<FILE_TYPE>0</FILE_TYPE>
<HASHEADERS>true</HASHEADERS>
<USE_RECIPIENT_ID>true</USE_RECIPIENT_ID>
</LIST_INFO>
I want to print the results of an SQL query in XUL with word-wrapping using the description tag. I have the following code:
<grid>
<columns>
<column flex="2" />
<column flex="1" />
</columns>
<rows datasources="chrome://glossary/content/db/development.sqlite3" ref="?" querytype="storage" >
<template>
<query>select distinct * from Terms</query>
<action>
<row uri="?">
<description value="?name" />
<description value="?desc" />
</row>
</action>
</template>
</rows>
This works for printing the data, but since I'm using the value attribute of description, there's no word-wrapping. I don't understand entirely what I'm doing with the value attribute, but I don't seem to be able to get the values of my SQL query in any other way. So, how could I get those values without the value tag?
Thanks.
So, if anyone's ever looking, I found this out on IRC:
You can use a textnode element to do this.
<description><textnode value="?name" /></description>
This will give you line-wrapping.