How can I create a txt file in xml using Sql server? - sql

How can i create the below xml file from sql server?
<Database>
<Tables>
<Table Name="Student"> <Files> <File FileName="Student_Info.txt" NumberOfRows="44" /> </Files>
<Columns>
<Column Name="Name" DataType="nvarchar" Length="50" />
<Column Name="Department" DataType="nvarchar" Length="30" />
<Column Name="Phone" DataType="nvarchar" Length="20" />
</Columns> </Table>
<Table Name="Teacher">
<Files>
<File FileName="Teacher.txt" NumberOfRows="33" />
</Files>
<Columns>
<Column Name="TID" DataType="ANSI INTEGER" IsPrimaryKey="true" />
<Column Name="TName" DataType="ANSI CHARACTER VARYING" Length="50" />
</Columns>
</Table>
</Database>
Here I want to make a database where all table data will save in a txt file and the Number of rows will change everytime.

This query would give you the current database format output like what you have
select
(
select TABLE_NAME as '#Name' ,
( select COLUMN_NAME as '#Name',
Data_type as '#DataType',
character_octet_length as '#Length'
FROM information_schema.COLUMNS C
WHERE IT.TABLE_NAME = C.TABLE_NAME
FOR XML PATH ('Column'), TYPE
),
(select
( SELECT distinct
d.physical_name as '#FileName',
i.rowcnt as '#NumberofRows'
FROM sys.sysindexes i,
sys.filegroups f,
sys.database_files d,
sys.data_spaces s
WHERE OBJECTPROPERTY(i.id, 'IsUserTable') = 1
AND f.data_space_id = i.groupid
AND f.data_space_id = d.data_space_id
AND f.data_space_id = s.data_space_id
AND IT.TABLE_NAME = OBJECT_NAME(i.id)
FOR XML path ('File'), Type
)
FOR XML PATH ('Files'), Type
)
from INFORMATION_SCHEMA.TABLES IT
for xml path ('Table'), TYPE
)
for xml path ('Databases')

Related

loop / Extract nodes from clob xml column in oracle pl sql

I have this xml content stored in a clob column of a table, I have to loop through the "molecule" nodes under the "reactantList" node,and store each "molecule" node into another table containing a list of molecules,
Any help please?
I tried with xmltype, xmlsequence, xmltable etc but did not work, I also have to specify the namespace "xmlns=.." somewhere as an argument to xmltype I think, to be able to make it work...
<cml xmlns="http://www.chemaxon.com" version="ChemAxon file format v20.20.0, generated by vunknown" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.chemaxon.com http://www.chemaxon.com/marvin/schema/mrvSchema_20_20_0.xsd">
<MDocument>
<MChemicalStruct>
<reaction>
<arrow type="DEFAULT" x1="-8.022119140625" y1="0.8333333333333334" x2="-3.5637858072916657" y2="0.8333333333333334" />
<reactantList>
<molecule molID="m1">
<atomArray>
<atom id="a1" elementType="C" x2="-13.938333333333334" y2="0.7083333333333333" />
<atom id="a2" elementType="O" x2="-15.478333333333333" y2="0.7083333333333333" lonePair="2" />
</atomArray>
<bondArray>
<bond id="b1" atomRefs2="a1 a2" order="1" />
</bondArray>
</molecule>
<molecule molID="m2">
<atomArray>
<atom id="a1" elementType="O" x2="-9.897119140624998" y2="0.8333333333333333" mrvValence="0" lonePair="3" />
</atomArray>
<bondArray />
</molecule>
</reactantList>
<agentList />
<productList />
</reaction>
</MChemicalStruct>
<MReactionSign toption="NOROT" fontScale="14.0" halign="CENTER" valign="CENTER" autoSize="true" id="o1">
<Field name="text">
<![CDATA[{D font=SansSerif,size=18,bold}+]]>
</Field>
<MPoint x="-11.730452473958332" y="0.6666666666666666" />
<MPoint x="-11.217119140624998" y="0.6666666666666666" />
<MPoint x="-11.217119140624998" y="1.18" />
<MPoint x="-11.730452473958332" y="1.18" />
</MReactionSign>
</MDocument>
</cml>
You can use:
INSERT INTO molecules (molecule)
SELECT x.molecule
FROM table_name t
CROSS APPLY XMLTABLE(
XMLNAMESPACES(
'http://www.w3.org/2001/XMLSchema-instance' AS "xsi",
DEFAULT 'http://www.chemaxon.com'
),
'/cml/MDocument/MChemicalStruct/reaction/reactantList/molecule'
PASSING XMLTYPE(t.xml)
COLUMNS
molecule XMLTYPE PATH '.'
) x
db<>fiddle here

Using SQL to Generate XML

I'm trying to use SQL to generate XML in the format:
<ImportSession>
<Batches>
<Batch>
<BatchFields>
<BatchField Name="Field1" Value="1" />
<BatchField Name="Field2" Value="2" />
<BatchField Name="Field3" Value="3" />
</BatchFields>
<Batch>
<Batches>
</ImportSession>
I'm using SQL Server 2008. I wrote this query:
SELECT
(SELECT
(SELECT
'Col' AS [#Name],
FiscalYear AS [#Value]
FROM [ICEM].[dbo].[ExportedBill]
WHERE ExportedBillID = 1
FOR XML PATH ('BatchField'), TYPE)
FROM [ICEM].[dbo].[ExportedBill]
WHERE ExportedBillID = 1
FOR XML PATH ('BatchFields'), ROOT ('Batch'), TYPE)
FROM
[ICEM].[dbo].[ExportedBill]
WHERE
ExportedBillID = 1
FOR XML PATH ('Batches'), ROOT ('ImportSession')
And this results in:
<ImportSession>
<Batches>
<Batch>
<BatchFields>
<BatchField Name="Col" Value="2015" />
</BatchFields>
</Batch>
</Batches>
</ImportSession>
What I need though is every column should have an entry in BatchField. Also I need the column name to show up in the name. So I should get:
<BatchField Name="FiscalYear" Value="2015" />
<BatchField Name="MeterNumber" Value="123456" />
<BatchField Name="Name" Value="John Smith" />
<BatchField Name="Utility" Value="Electricity" />
So can anyone tell me how I modify my query to get what I need?
EDIT:
I figured it out. I needed a second nested Select. I need one for each column. If they proceeding selects use the same tags as a previous Select then the information is concatanated under the same parent tag
SELECT
(SELECT
(SELECT
'FiscalYear' AS [#Name],
FiscalYear AS [#Value]
FROM [ICEM].[dbo].[ExportedBill]
WHERE ExportedBillID = 1
FOR XML PATH ('BatchField'), TYPE),
(SELECT 'FiscalPeriod' AS [#Name],
FiscalPeriod AS [#Value]
FROM [PEEL_ICEM].[dbo].[ExportedBill]
WHERE ExportedBillID = 1
FOR XML PATH ('BatchField'), TYPE)
FROM [ICEM].[dbo].[ExportedBill]
WHERE ExportedBillID = 1
FOR XML PATH ('BatchFields'), ROOT ('Batch'), TYPE)
FROM
[ICEM].[dbo].[ExportedBill]
WHERE
ExportedBillID = 1
FOR XML PATH ('Batches'), ROOT ('ImportSession')
Thing is though, there will be around 70 columns in this table. Ill brute force it for now, but if anyone knows of a better way to do this please let me know. Cheers
You can create separate child elements by adding a blank column separator. e.g.
DECLARE #T TABLE
( FiscalYear INT,
MeterNumber INT,
Name VARCHAR(255),
Utility VARCHAR(255)
);
INSERT #T VALUES (2015, 123456, 'John Smith', 'Electricity');
SELECT [BatchField/#Name] = 'FiscalYear',
[BatchField/#Value] = FiscalYear,
'',
[BatchField/#Name] = 'MeterNumber',
[BatchField/#Value] = MeterNumber,
'',
[BatchField/#Name] = 'Name',
[BatchField/#Value] = Name,
'',
[BatchField/#Name] = 'Utility',
[BatchField/#Value] = Utility
FROM #T
FOR XML PATH('BatchFields'), ROOT('Batch');
Which gives:
<Batch>
<BatchFields>
<BatchField Name="FiscalYear" Value="2015" />
<BatchField Name="MeterNumber" Value="123456" />
<BatchField Name="Name" Value="John Smith" />
<BatchField Name="Utility" Value="Electricity" />
</BatchFields>
</Batch>

How do I extract data from an XMLTYPE field by attribute?

Forgive me for being a total beginner.
I am looking at a column named FORM_XML that is described as data type XMLTYPE.
The contents of one field is:
<Form FormID="0" Name="Preventive Care(F)">
<FormObject Name="prevcare01" Type="DateTime" Label="Physical Exam" EditValue="04/05/2007" />
<FormObject Name="prevcare02" Type="DateTime" Label="Lipid Profile" EditValue="NoEditValue" />
<FormObject Name="prevcare03" Type="DateTime" Label="Health Care Proxy review" EditValue="NoEditValue" />
<FormObject Name="prevcarecomm" Type="Text" Label="Comments" EditValue="NoEditValue" />
</Form>
The goal is to extract the EditValue date where Label="Physical exam". In this example, the date 04/05/2007 is what I want to extract. Is there a magic query that can accomplish this?
Existing questions haven't helped because their XML data is structured differently. Is my XML data structured wrong because it doesn't contain namespaces, and specific labels?
FOLLOW-UP QUESTION:
I ran
SELECT Extract(form_xml, '/Form/FormObject/#EditValue') FROM patient_form;
And got the EditValue for all FormObjects concatenated together. Is it possible to filter out just the EditValue where Label="Physical exam"?
You can use XMLTABLE to convert XML to rows and columns and then apply your filter.
Query:
SQL> with x(y) as (
select xmltype('<Form FormID="0" Name="Preventive Care(F)">
<FormObject Name="prevcare01" Type="DateTime" Label="Physical Exam" EditValue="04/05/2007" />
<FormObject Name="prevcare02" Type="DateTime" Label="Lipid Profile" EditValue="NoEditValue" />
<FormObject Name="prevcare03" Type="DateTime" Label="Health Care Proxy review" EditValue="NoEditValue" />
<FormObject Name="prevcarecomm" Type="Text" Label="Comments" EditValue="NoEditValue" />
</Form>') from dual
)
select z.*
from x cross join
xmltable('Form/FormObject' passing x.y
columns label_ varchar2(30) path '#Label',
editvalue_ varchar2(30) path '#EditValue'
) z
where z.label_ = 'Physical Exam';
Result:
LABEL_ EDITVALUE_
------------------------------ ------------------------------
Physical Exam 04/05/2007
Or use XQuery to filter it before converting to rows and columns.
Query:
SQL> with x(y) as (
select xmltype('<Form FormID="0" Name="Preventive Care(F)">
<FormObject Name="prevcare01" Type="DateTime" Label="Physical Exam" EditValue="04/05/2007" />
<FormObject Name="prevcare02" Type="DateTime" Label="Lipid Profile" EditValue="NoEditValue" />
<FormObject Name="prevcare03" Type="DateTime" Label="Health Care Proxy review" EditValue="NoEditValue" />
<FormObject Name="prevcarecomm" Type="Text" Label="Comments" EditValue="NoEditValue" />
</Form>') from dual
)
select z.*
from x cross join
xmltable('for $i in /Form/FormObject
where $i/#Label = "Physical Exam"
return $i' passing x.y
columns label_ varchar2(30) path '#Label',
editvalue_ varchar2(30) path '#EditValue'
) z;
Result:
LABEL_ EDITVALUE_
------------------------------ ------------------------------
Physical Exam 04/05/2007
Namespaces are usually what makes life complicated, no namespace should be simpler.
/Form/FormObject/#EditValue

StoredProcedure returning multiple resultset Sql To Linq using designer

I want to get multiple resultsets from a storedProc using sql to linq. I was not able to generate it from designer so I wrote below code in designer.cs file. But whenever I add something to designer, it refreshes the designer with the markup in .dbml file and hence it removes the below code every time I add something. I have to copy it every time. If I can get corresponding dbml markup for this, it would be great.
[Function(Name = "dbo.GetAllModulesAndOptions")]
[ResultType(typeof(Module))]
[ResultType(typeof(ModuleOption))]
public IMultipleResults GetAllModules()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
return ((IMultipleResults)(result.ReturnValue));
}
I've already defined Module and ModuleOption as tables.
Now when I add below markup in .dbml file it complains
DBML1114: The Name attribute 'Module' of the Type element is already used by another type.
<Function Name="dbo.GetAllModulesAndOptions" Method="GetAllModules">
<ElementType Name="Module">
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt NOT NULL" CanBeNull="false" />
<Column Name="ModuleName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="Description" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
<Column Name="SalesDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="ParentModuleId" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
<ElementType Name="ModuleOption">
<Column Name="ModuleOptionId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ModuleOptionName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="ModuleOptionDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="DefaultPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt" CanBeNull="true" />
<Column Name="InUse" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
</Function>
I'm using Visual Studio 2008 SP1
Add the method to the partial class for the data context.
You achieve this by adding a file with the same name as the data context alongside the dbml file, and use the class declaration:
public partial class YourDataContext
{
[Function(Name = "dbo.GetAllModulesAndOptions")]
[ResultType(typeof(Module))]
[ResultType(typeof(ModuleOption))]
public IMultipleResults GetAllModules()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo (MethodInfo.GetCurrentMethod())));
return ((IMultipleResults)(result.ReturnValue));
}
}
I'm replying my own answer.
One cannot use the already defined type for result set of stored procedure. So I had to change the name of ElementType to ModuleResult and ModuleOptionResult.
<Function Name="dbo.GetAllModulesAndOptions" Method="GetAllModules">
<ElementType Name="ModuleResult">
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt NOT NULL" CanBeNull="false" />
<Column Name="ModuleName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="Description" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
<Column Name="SalesDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="ParentModuleId" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
<ElementType Name="ModuleOptionResult">
<Column Name="ModuleOptionId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ModuleOptionName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="ModuleOptionDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="DefaultPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt" CanBeNull="true" />
<Column Name="InUse" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
</Function>
Here are the steps which I took to solve the above problem.
Delete the .designer.cs file
Add above markup to the .dbml file
Exclude .dbml and .dbml.layout file
Include .dbml and .dbml.layout file (this will generate .designer.cs file again but will not include it in the project).
Include .designer file in project.
Get the list of Module type and ModuleOption type as below.
var modules = from row in results.GetResult<ModuleResult>().ToList()
select new Module
{
ModuleId = row.ModuleId,
ModuleName = row.ModuleName,
Description = row.Description,
SalesDesc = row.SalesDesc,
ParentModuleId = row.ParentModuleId
};
var moduleOptions = from row in results.GetResult<ModuleOptionResult>().ToList()
select new ModuleOption
{
ModuleOptionId = row.ModuleOptionId,
ModuleOptionName = row.ModuleOptionName,
ModuleOptionDesc = row.ModuleOptionDesc,
DefaultPrice = row.DefaultPrice,
ModuleId = row.ModuleId,
InUse = row.InUse
};
UPDATE
Still a better way.
Right click the dbml file in solution explorer and select open with. Choose XML Editor and when you save the file within visual studio it automatically generates the designer.cs file.

Hibernate - New colums from a joined table [duplicate]

This question already has answers here:
Hibernate One-To-Many Unidirectional on an existing DB
(4 answers)
Closed 2 years ago.
I have a class User object. I am trying to load this object from the Database using Hibernate.
My SQL statement is:
SELECT
users.uid AS uid,
users.deleted AS deleted,
users.username AS username,
users.passwd AS passwd,
users.disabled AS disabled,
users.lockout AS lockout,
users.expires AS expires,
data_firstname.value AS firstname,
data_lastname.value AS lastname
FROM
ac_users as users
LEFT JOIN
ac_userdef_data as data_firstname
ON
users.uid = data_firstname.parentuid AND
data_firstname.fieldname like 'firstname'
LEFT JOIN
ac_userdef_data as data_lastname
ON
users.uid = data_lastname.parentuid AND
data_lastname.fieldname like 'lastname'
WHERE
users.deleted = 0
My mapping for the User class is:
<class name="com.agetor.commons.security.User" table="ac_users">
<id name="uid" column="uid" type="long" >
<generator class="native"/>
</id>
<property name="deleted" column="deleted" />
<property name="username" column="username" />
<property name="password" column="passwd" />
<property name="firstname" column="firstname" />
<property name="lastname" column="lastname" />
<property name="disabled" column="disabled" />
<property name="lockout" column="lockout" />
<property name="expires" column="expires" />
</class>
My problem is that the table ac_users does not have a column 'firstname' or 'lastname'
These columns, only exist in my resultset from the SQL-join statement.
They do also not exist in the ac_userdef_data table. There i have 2 colums: fieldname and value. and 2 rows:
fieldname = 'firstname' with some value in the value column
and another row with
fieldname = 'lastname' with some value in the value column
How do i change my mapping file, so that Hibernate will understand that it needs to load the firstname and lastname column into my firstname and lastname fields on my POJO, while those columns dont actually exist on the referenced ac_users table.?
I now have some working code. The trick was to specify a loading Query for the User class. Hibernate then validates against the return from the Query instead of the Table design.
Class mapping
<class name="com.agetor.commons.security.User" table="ac_users">
<id name="uid" column="uid" type="long" >
<generator class="native"/>
</id>
<property name="deleted" column="deleted" />
<property name="username" column="username" />
<property name="password" column="passwd" />
<property name="firstname" column="firstname" />
<property name="lastname" column="lastname" />
<property name="disabled" column="disabled" />
<property name="lockout" column="lockout" />
<property name="expires" column="expires" />
<loader query-ref="GetAllUsers" />
</class>
My Query declaration
<sql-query name="GetAllUsers">
<return alias="user" class="com.agetor.commons.security.User" />
<![CDATA[
SELECT
users.uid AS uid,
users.deleted AS deleted,
users.username AS username,
users.passwd AS passwd,
users.disabled AS disabled,
users.lockout AS lockout,
users.expires AS expires,
data_firstname.value AS firstname,
data_lastname.value AS lastname
FROM
ac_users as users
LEFT JOIN
ac_userdef_data as data_firstname
ON
users.uid = data_firstname.parentuid AND
data_firstname.fieldname like 'firstname'
LEFT JOIN
ac_userdef_data as data_lastname
ON
users.uid = data_lastname.parentuid AND
data_lastname.fieldname like 'lastname'
WHERE
users.deleted = 0
]]>
</sql-query>
I had to use the line <return alias="user" class="com.agetor.commons.security.User" /> so that the returned collection was typed correctly