How to get first element by XPath in Oracle - sql

In my Oracle db I have records like this one:
<ROOT>
<Event>
<Type>sldkfvjhkljh</Type>
<ID>591252</ID>
</Event>
<Data>
<File>
<Name>1418688.pdf</Name>
<URL>/591252/1418688.pdf</URL>
</File>
<File>
<Name>1418688.xml</Name>
<URL>/591252/1418688.xml</URL>
</File>
</Data>
</ROOT>
I need to extract a value from the first <Name> tag. If I try:
Select xmltype(xml_data).extract('//Name[1]/text()').getStringVal() from MY_TABLE
I get:
1418688.pdf1418688.xml
Why is that and how can I get just 1418688.pdf?
Oracle Version:
Oracle Database 10g Enterprise Edition
Release 10.2.0.4.0 - 64bi

I think that both Name elements are #1 in this doc, because in their nodes they are each first. Try //File[1]/Name/text()

Related

Liquibase giving syntax error for an included SQL file,which is otherwise correct

I have a change log file,part of which looks like:
<include file="ChangeSets/00_SessionAuth.xml"/>
<include file="ChangeSets/01_Legacy_Baseline_V197_ANB.xml" context="legacy"/>
<include file="ChangeSets/02_V198_ANB.xml" context="non-legacy"/>
The change set 01_Legacy_Baseline_V197_ANB.xml has 197 sql scripts included,which are part of legacy database.
The change set 02_V198_ANB.xml is defined as:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<include file="ChangeSets/sql/Dummy_schema/V198_AddColumn.sql"/>
</databaseChangeLog>
When i run the Liquibase update with context as non legacy, i get the following error :
Unexpected error running Liquibase: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=SET SCEHMA = Dummy_schema;;BEGIN-OF-STATEMENT;<space>, DRIVER=3.62.56 [Failed SQL: SET SCEHMA = Dummy_schema;
The SQL file itself is correct.
I think this is an issue related to end delimiter or splitStatements.
The SQL goes like this:
SET SCEHMA = Dummy_schema;
ALTER TABLE T1 ADD COLUMN C1 VARCHAR(35)
ADD COLUMN C2 INTEGER;
Call Sysproc.admin_cmd ('REORG TABLE dummy_schema.T1');
ALTER TABLE T2 ADD COLUMN CT1 INTEGER;
Call Sysproc.admin_cmd ('REORG TABLE dummy_schema.T2');
We are using DB2 V10.5.
Can someone also provide the list of attributes,we can use with tag.
Regards
I think your assertion that
the SQL file itself is correct
is incorrect. That is valid SQL if it was run through the db2 command line application, but it is not valid SQL to be sent through a JDBC query, which is what Liquibase does.

SQL Server inside CDATA block of XML

The meaning of $> inside the CDATA block.I am trying to understand the part inside the CDATA block of an XML code file,the parts where $> is used.What is the use of it?
<sqlTask name='LOGIN_USER'>
<![CDATA[
SELECT owner_id $>REGISTRAR_PK, SYSDATE $>TIMESTAMP, ops\$rs3.report_seq.nextval $>REPORT_ID
FROM ops\$rs3.smdi_owners
WHERE user_name = UPPER($LOGIN_USER)
]]>
<error text='Registrar: $LOGIN_USER - Unknown user.'/>
</sqlTask>

Read .csv table and print it as SQL query output

I am using a bastardised version of T-SQL to generate reports about information within a database driven CAD software (Solidworks Electrical). I am trying to generate a Table of Contents. Due to limitations within the software, I have to generate this table using SQL.
What I would like to do is create the Table of Contents in Excel, save it as a .csv, and have my SQL query read this file and spit it out as an output.
Example Table:
Sheet,System
1,Radios
2,Processors
3,Navigation
After some searching I've been unable to find a solution myself. My problems are:
1) Read a .csv file stored on my harddrive
2) Turn this .csv file into a table (cant get stored on the database, is just temporary while we run the query)
3) Output the data in this table as the results of the query
I have tried to use the following to read my .csv table, but recieve the error "Syntax error, permission violation, or other nonspecific error". So it's possible my software just won't allow me to read external files. (NB, my software uses ]] [[ instead of quotes....)
select
]]col1[[,
]]col2[[,
]]col3[[
from openrowset('MSDASQL'
,'Driver={Microsoft Access Text Driver (*.txt, *.csv)}'
,'select * from D:\SQL Queries\input.CSV')
Any assistance would be much appreciated! Thanks
This sql works for me:
select * from openrowset (bulk N'C:\Temp\source.csv', formatfile = N'C:\Temp\format.xml', firstrow=2) SourceFile
Content of source.csv is this:
Sheet,System
1,Radios
2,Processors
3,Navigation
Content of format.xml is this:
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=","/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="128" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="ID" xsi:type="SQLINT"/>
<COLUMN SOURCE="2" NAME="Name" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>

Converting Complex XML to CSV

I have some (complex to me) XML code that I need to convert into CSV, I need absolutely every value added to the CSV for every submission, I have tried a few basic things however I cant get past the deep nesting and the different structures of this file.
Could someone please help me with a powershell script that would, I have started but cannot get the output of all data out I only get Canvas Results
Submissions.xml To large to post here (102KB)
$d=([xml](gc submissions.xml)).CANVASRESULTS | % {
foreach ($i in $_.CANVASRESULTS) {
$o = New-Object Object
Add-Member -InputObject $o -MemberType NoteProperty -Name Submissions -Value $_.Submission
Add-Member -InputObject $o -MemberType NoteProperty -Name Submission -Value $i
$o
}
}
$d | ConvertTo-Csv -NoTypeInformation -Delimiter ","
Anytime a complex XML has deeply nested structures and you require migration into a flat file format (i.e., txt, csv, xlsx, sql), consider using XSLT to simplify your XML format. As information, XSLT is a declarative, special-purpose programming language used to style, re-format, re-structure XML/HTML and other SGML markup documents for various end-use purposes. Aside - SQL is also a declarative, special-purpose programming language.
For most softwares to import XML into flat file formats in two dimensions of rows and columns, XML files must follow repeating elements (i.e., rows/records) with one level of children for columns/fields:
<data>
<row>
<column1>value</column1>
<column1>value</column1>
<column1>value</column1>
...
</row>
<row>
...
</data>
Nearly every programming language maintains an XSLT processor including PowerShell, Java, C#, Perl, PHP, Python, SAS, even VBA with your everyday MS Excel. For your complex XML, below is an example XSLT stylesheet with following output. Do note I manually create nodes based on values from original XML:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="CanvasResult">
<Data>
<xsl:for-each select="//Responses">
<Submission>
<Fitter><xsl:value-of select="Response[contains(Label, 'Fitter Name')]/Value"/></Fitter>
<Date><xsl:value-of select="Response[Label='Date']/Value"/></Date>
<Time><xsl:value-of select="Response[Label='Time']/Value"/></Time>
<Client><xsl:value-of select="Response[Label='Client']/Value"/></Client>
<Machine><xsl:value-of select="Response[Label='Machine']/Value"/></Machine>
<Hours><xsl:value-of select="Response[Label='Hours']/Value"/></Hours>
<Signature><xsl:value-of select="Response[Label='Signature']/Value"/></Signature>
<SubmissionDate><xsl:value-of select="Response[Label='Submission Date:']/Value"/></SubmissionDate>
<SubmissionTime><xsl:value-of select="Response[Label='Submission Time:']/Value"/></SubmissionTime>
<Customer><xsl:value-of select="Response[Label='Customer:']/Value"/></Customer>
<PlantLocation><xsl:value-of select="Response[Label='Plant Location']/Value"/></PlantLocation>
<PlantType><xsl:value-of select="Response[Label='Plant Type:']/Value"/></PlantType>
<PlantID><xsl:value-of select="Response[Label='Plant ID:']/Value"/></PlantID>
<PlantHours><xsl:value-of select="Response[Label='Plant Hours:']/Value"/></PlantHours>
<RegoExpiryDate><xsl:value-of select="Response[Label='Rego Expiry Date:']/Value"/></RegoExpiryDate>
<Comments><xsl:value-of select="Response[Label='Comments:']/Value"/></Comments>
</Submission>
</xsl:for-each>
</Data>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version='1.0' encoding='UTF-8'?>
<Data>
...
<Submission>
<Fitter>Damian Stewart</Fitter>
<Date/>
<Time/>
<Client/>
<Machine/>
<Hours/>
<Signature/>
<SubmissionDate>28/09/2015</SubmissionDate>
<SubmissionTime>16:30</SubmissionTime>
<Customer>Dicks Diesels</Customer>
<PlantLocation/>
<PlantType>Dozer</PlantType>
<PlantID>DZ09</PlantID>
<PlantHours>2213.6</PlantHours>
<RegoExpiryDate>05/03/2016</RegoExpiryDate>
<Comments>Moving tomorrow from Daracon BOP to KCE BOP S6A Dam
Cabbie to operate</Comments>
</Submission>
...
</Data>
From there, you can import the two-dimensional XML into a usable rows/columns format. Below are the same import into an MS Access Database and MS Excel spreadsheet. You will notice gaps in the data due to XML content not populating the created nodes (handled in XSLT). A simple SQL cleanup can render final dataset.
Database Import

SQL enddelimiter in Liquibase 3.1 does not seem to work

I have a trigger written like below
create or replace trigger departments_bi before insert on departments_test
for each row
when (new.id is null)
begin
select departments_seq.nextval into :new.id from dual;
end;
/
I am referring to this trigger inside a changeset xml using sqlfile
<?xml version="1.0" encoding="UTF-8" ?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="raghav" id="004" runOnChange="true">
<sqlFile dbms="oracle"
encoding="ASCII"
endDelimiter="\n"
path="Triggers.sql"
relativeToChangelogFile="true"
splitStatements="false"
stripComments="false"/>
<rollback>
drop trigger departments_bi
</rollback>
</changeSet>
</databaseChangeLog>
Using Ant UpdateDatabase command am generating a SQL File with all the changes. Am also using exec task to execute the generated SQL with all changes against a target DB.
<updateDatabase
changeLogFile="${checkout}/Trigger.xml"
driver="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#${machineId}:${targetDB_Port}:${targetDB}"
username="${targetDB_User}"
password="${targetDB_Password}"
classpathref="classpath"
outputFile="${env1.WORKSPACE}/Update_MNT.sql"
/>
<echo message="Beginning to execute Update_MNT.sql to target DB ${targetDB} using username ${targetDB_user}"/>
<exec dir="${env1.WORKSPACE}" executable="sqlplus" failonerror="true">
<arg value="${targetDB_User}/${targetDB_Password}#${tnstargetDB}"/>
<arg value="#Update_MNT.sql"/>
</exec>
The problem am having is with the generated SQL file. Its including the contents of the Trigger.sql file with an extra ; at the end .. So while executing the Update_MNT.sql using exec command. The sqlplus fails because of the additional ; after / in the generated SQL file. How to resolve this issue?
-- Changeset E:/Jenkins_Liquibase_Test/Triggers.xml::004::raghav
create or replace trigger departments_bi before insert on departments_test
for each row
when (new.id is null)
begin
select departments_seq.nextval into :new.id from dual;
end;
/;
There are currently some issues with endDelimiter, formatted SQL changeset and updateSQL command:
CORE-1097,
CORE-1877,
CORE-2199.