Datatable as a cell of another datatable in SQL server - sql-server

Is there any methode to return a data table as a particular cell of another datatable.
Ie, I hav a datatable with 3 columns. the second column contains multiple values for a single record.... If there any methode to attain this through a single table....
Thanks in advance

It is not possible to have a table as a column. You can have a XML column to store structured information. XML columns can also be queried.
More info about xml data type can be found here http://msdn.microsoft.com/en-us/library/ms190936%28v=sql.90%29.aspx.
Example of what you can do with xml.
declare #T table (id int, data xml)
insert into #T values (1, '<root><val1>1</val1><val2>2</val2></root>')
insert into #T values (2, '<root><val1>11</val1><val2>12</val2></root>')
select
id,
r.r.value('val1[1]', 'int') as Val1,
r.r.value('val2[1]', 'int') as Val2
from #T
cross apply
data.nodes('root') r(r)
Result
id Val1 Val2
1 1 2
2 11 12

Related

Export data from Microsoft SQL Server using a query to target data

I know how to generate scripts to script insert lines allowing me to backup some data. I was wondering though if it was possible to write a query (using WHERE clause as an example) to target a very small subset of data in a very large table?
In the end I want to generate a script that has a bunch of insert lines and will allow for inserting primary key values (where it normally would not let you).
SSMS will not let you to have the INSERT queries for specific rows in a table. You can do this by using GenerateInsert stored procedure. For example :
EXECUTE dbo.GenerateInsert #ObjectName = N'YourTableName'
,#SearchCondition='[ColumnName]=ColumnValue';
will give you similar result for the filtered rows specified in the #SearchCondition
Let's say your table name is Table1 which has columns Salary & Name and you want the insert queries for those who have salary greater than 1000 whose name starts with Mr., then you can use this :
EXECUTE dbo.GenerateInsert #ObjectName = N'Table1'
,#SearchCondition='[Salary]>1000 AND [Name] LIKE ''Mr.%'''
,#PopulateIdentityColumn=1;
If I read your requirement correctly, what you actually want to do is simply make a copy of some data in your table. I typically do this by using a SELECT INTO. This will also generate the target table for you.
CREATE TABLE myTable (Column1 int, column2 NVARCHAR(50))
;
INSERT INTO myTable VALUES (1, 'abc'), (2, 'bcd'), (3, 'cde'), (4, 'def')
;
SELECT * FROM myTable
;
SELECT
*
INTO myTable2
FROM myTable WHERE Column1 > 2
;
SELECT * FROM myTable;
SELECT * FROM myTable2;
DROP TABLE myTable;
DROP TABLE myTable2;
myTable will contain the following:
Column1 column2
1 abc
2 bcd
3 cde
4 def
myTable2 will only have the last 2 rows:
Column1 column2
3 cde
4 def
Edit: Just saw the bit about the Primary Key values. Does this mean you want to insert the data into an existing table, rather than just creating a backup set? If so, you can issue SET IDENTITY_INSERT myTable2 ON to allow for this.
However, be aware that might cause issues in case the id values you are trying to insert already exist.

How to enter null for missed columns in csv?

I try to perform bulk insert from csv file.
MY csv file having 7 columns but table contains 8 columns.
i can able to perform bulk insert with below query if my table having 8 columns only.
BULK INSERT Table_Name FROM 'E:\file\input.csv' WITH (ROWTERMINATOR = '0x0A',CODEPAGE = 'ACP',FIELDTERMINATOR = ',',KEEPNULLS, ROWS_PER_BATCH = 10000)
but my csv contains only 7 columns this leads below error..,
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 1, column 8 (datecolumn).
Can anyone suggest me way to resolve this without using FormatFile?
Create a view with the 7 columns and insert into that view instead.
Example with fewer columns:
CREATE TABLE test_table(col1 int, col2 int, col3 int)
go
CREATE VIEW v_test_table
as
SELECT col1, col2
FROM test_table
go
INSERT v_test_table
SELECT 1,2
go
SELECT * FROM test_table

Parse XML and generate new rows through SQL Query

I've the input data in SQL table in below format:
ID Text
1 <Key><Name>Adobe</Name><Display>Ado</Display></Key><Key>.....</Key>
2 <Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>
There can be multiple keys for each ID.There could be several thousand rows in a table in above format. I've to generate the final sql output in below format
ID Name Display Version
1 Adobe Ado
1 xyz yz 1.2
2 Microsoft 1.1
I am using the below query to parse Text column, but getting all data in one row. How can I split that data in multiple rows as indicated above.
SELECT
CAST(CAST(Text AS XML).query('data(/Key/Name)') AS VARCHAR(MAX)) AS Name,
CAST(CAST(Text AS XML).query('data(/Key/Display)') as VARCHAR(MAX)) AS DisplayName,
CAST(CAST(Text AS XML).query('data(/Key/Version)') AS VARCHAR(MAX)) AS Version
FROM
ABC where ID = 1
Currently I am running this query for each ID at a time. Is there a way to run for all ID's together. Also, is there any other efficient way to get the desired output.
Here is the example:
-- Sample demonstrational schema
declare #t table (
Id int primary key,
TextData nvarchar(max) not null
);
insert into #t
values
(1, N'<Key><Name>Adobe</Name><Display>Ado</Display></Key><Key><Name>xyz</Name><Display>yz</Display><Version>1.2</Version></Key>'),
(2, N'<Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>');
-- The actual query
with cte as (
select t.Id, cast(t.TextData as xml) as [XMLData]
from #t t
)
select c.Id,
k.c.value('./Name[1]', 'varchar(max)') as [Name],
k.c.value('./Display[1]', 'varchar(max)') as [DisplayName],
k.c.value('./Version[1]', 'varchar(max)') as [Version]
from cte c
cross apply c.XMLData.nodes('/Key') k(c);
Different type can be corrected with the in-place cast/convert done in CTE (or equivalent subquery).

MSSQL Insert Data From One Table To Another With Fixed Value

Hello I would like to insert in a table called Data multiple columns from another table called SourceTable and one colum that has a standar value for every row added in Data.
Assume that you have Column1 and Column2 in the table called SourceTable and source_id is precalculated and it will be the same for every row added into Data on this query.
INSERT INTO Data (Columns1, Column2, source_id)
SELECT Column1, Column2
FROM SourceTable
UNION SELECT 2;
I tried this one but is not working, most likely because the SELECT 2 returns only one row.
Your issue is that you're giving SQL 3 columns to insert 2 values into, if source_id is going to be 2 as your union selects then you'd want something like this;
INSERT INTO Data (Columns1, Column2, source_id)
SELECT Column1, Column2, 2
FROM SourceTable
The number of columns you're inserting needs to match the number of columns that you're inserting to. The way you were doing it would have produced this result;
Column1 Column2 source_id
Value1 Value2
2
but even the union would have failed as the queries that you're unioning need to have the same number of columns.

SQL Server table to xml

this time i have question how to convert MSSQL table to XML
My source SQL table:
+-----------+-----------------+
|atributname|atributvalue |
+-----------+-----------------+
|phone |222 |
|param4 |bbbbcdsfceecc |
|param3 |bbbbcdsfceecc |
|param2 |bbbbcdsfccc |
+-----------+-----------------+
Expected result sample:
<items>
<phone>222</phone>
<prama4>bbbbcdsfceecc</param4>
<param3>bbbbcdsfceecc</param3>
<param2>bbbbcdsfccc</param2>
</items>
I tried lot of variations of the following query
SELECT atributname,atributvalue
FROM sampletable FOR XML PATH (''), ROOT ('items');
but results are not good :( should be exactly like in "Expected result sample"
any help
ps
Script to create sampletable:
create table sampletable
(atributname varchar(20),
atributvalue varchar(20))
insert into sampletable (atributname,atributvalue)
values ('phone','222');
insert into sampletable (atributname,atributvalue)
values ('param4','bbbbcdsfceecc');
insert into sampletable (atributname,atributvalue)
values ('param3','bbbbcdsfceecc');
insert into sampletable (atributname,atributvalue)
values ('param2','bbbbcdsfccc');
That's not how FOR XML works. It's columns that get turned into XML elements, not rows. In order to obtain the expected result, you would need to have columns named phone, param4, and so on - not rows with these values in attributename.
If there are specific elements you want in the XML, you could perform a pivot on the data first, then use FOR XML.
Example of a pivot would be:
SELECT [phone], [param2], [param3], [param4]
FROM
(
SELECT attributename, attributevalue
FROM attributes
) a
PIVOT
(
MAX(attributevalue)
FOR attributename IN ([phone], [param2], [param3], [param4])
) AS pvt
FOR XML ROOT('items')
Of course the aggregate will only work if attributevalue is a numeric data type. If it's a character-type column, then you'll have some trouble with the pivot, as there are no built-in string aggregates in SQL server AFAIK...
ok
finally i have done this in several ways,
but this is simplest version suitable for medium dataset
declare #item nvarchar(max)
set #item= (SELECT '<' + atributname +'>' +
cast(atributvalue as nvarchar(max)) +'</' + atributname +'>'
FROM sampletable FOR XML PATH (''), ROOT ('items'));
select replace(replace(#item,'<','<'),'>','>')

Resources