SQL Server Indonesia User Groups Community July 2009 - Posts - kasim.wirama

July 2009 - Posts

How to Migrate Non XML Column into XML Column
26 July 09 11:27 AM | kasim.wirama | with no comments

How to Migrate Non XML Column into XML Column

By : Kasim Wirama, MCITP, MCDBA

 

You might store xml data in text or varchar column type in SQL Server 2000 or previous version because it doesn’t support XML data type for storage. Now SQL Server 2005 and SQL Server 2008 support XML data type natively. It means that developer could declare XML variable, XML column, XML input/output parameters in stored procedure and user defined function and return value from user defined function; so converting xml data in text or varchar column type into xml column type is recommended because you can put high performance XML validation and very easy to query XML data with available XQuery methods.

Here is safe procedure to do conversion into XML column:

1.       Add temporary column with varchar(max) or nvarchar(max) or text type

2.       Set value from a source varchar column into step 1

3.       Drop source varchar column

4.       Create new column whose name is same as dropped column on step 3.

5.       Update back column in step 4 from value of column in step 2.

6.       Drop the temporary column.

Here is sample how to do this.

CREATE TABLE dbo.CustomerSalesRecord
(
  CustomerId int primary key,
  SalesRecord nvarchar(8000)
);
GO
INSERT INTO dbo.CustomerSalesRecord
SELECT c.customerId,
(

SELECT
FROM sales.salesorderheader as h
WHERE h.CustomerId = c.CustomerId
FOR  XML AUTO, ROOT(‘Orders’)

) as SalesRecord

FROM Sales.Customer as c;

1.       First step

ALTER TABLE dbo.CustomerSalesRecord
ADD SalesRecord_temp NVARCHAR(MAX);

 

2.       Second step
UPDATE dbo.CustomerSalesRecord
SET SalesRecord_temp = SalesRecord;

 

3.       Third step

ALTER TABLE dbo.CustomerSalesRecord
DROP COLUMN SalesRecord;

 

4.       Fourth step
ALTER TABLE dbo.CustomerSalesRecord
ADD SalesRecord XML;

 

5.       Fifth step

UPDATE dbo.CustomerSalesRecord
SET SalesRecord = CONVERT(XML, SalesRecord_temp);

 

6.       Sixth step

ALTER TABLE dbo.CustomerSalesRecord
DROP COLUMN SalesRecord_temp;

  
Filed under:
Detect Database Blocking Issue with SQL Server Dynamic Management View
23 July 09 02:00 AM | kasim.wirama | with no comments

Detect Database Blocking Issue with SQL Server Dynamic Management View

By : Kasim Wirama, MCITP, MCDBA

DBA has responsibility to maintain database from backup-restore, data integrity until smooth database daily operation. Most common problem regarding to database operation especially busy database activity is blocking and deadlocking. For this posting, I show you how to detect blocking on your SQL Server by using DMV (Dynamic Management View).

DMV has been introduced since SQL Server 2005. DMV for detecting blocking is sys.dm_tran_locks. Many advantage you use the DMV over sp_lock, sp_who2, sp_who and the like. Its advantages are that the DMV could show you resource location and you could export resultset for further analysis.

Back to sys.dm_tran_locks, you can detect blocking by joining to the DMV itself as query shown below
SELECT
l.*
FROM sys.dm_tran_locks as l
JOIN sys.dm_tran_locks as l1
ON l.resource_associated_entity_id = l1.resource_associated_entity_id
WHERE l.request_status <> l1.request_status
AND
( l.resource_description = l1.resource_description OR (l.resource_description IS NULL AND l1.resource_description IS NULL))

To see blocking scenario you can create sample table below :

USE tempdb
GO
CREATE TABLE test (cola varchar(10));
GO
INSERT INTO test VALUES (‘a’);

Open first connection (in SSMS open new window designer), and issue then execute query below :
USE tempdb
GO
BEGIN TRAN
UPDATE test SET cola = ‘b’;
WAITFOR DELAY ’00:10:00’;
ROLLBACK TRAN

Open second connection, issue the below :

USE tempdb
GO
SELECT * FROM test;

Execute the DMV then it display 2 records, to display object name getting involved in blocking, you can issue query below :

SELECT
db_name(l.resource_database_id) as [database name],
CASE l.resource_type
  WHEN ‘object’ then object_name(l.resource_associated_entity_id)
  WHEN ‘database’ then ‘databae’
  ELSE
    CASE WHEN l.resource_database_id = db_id() THEN
       (SELECT object_Name(object_id) FROM sys.partitions WHERE hobt_id = l.resource_associated_entity_id)
    ELSE NULL
    END
END,
l.*
FROM sys.dm_tran_locks as l
JOIN sys.dm_tran_locks as l1
ON l.resource_associated_entity_id = l1.resource_associated_entity_id
WHERE l.request_status <> l1.request_status
AND
( l.resource_description = l1.resource_description OR (l.resource_description IS NULL AND l1.resource_description IS NULL));

If you need to know what queries getting involved with blocking you can get query information from sys.dm_exec_requests and DMV function : sys.dm_exec_sql_text. Here is the DMV query :

SELECT
db_name(l.resource_database_id) as [database name],
CASE l.resource_type
  WHEN ‘object’ then object_name(l.resource_associated_entity_id)
  WHEN ‘database’ then ‘databae’
  ELSE
    CASE WHEN l.resource_database_id = db_id() THEN
       (SELECT object_Name(object_id) FROM sys.partitions WHERE hobt_id = l.resource_associated_entity_id)
    ELSE NULL
    END
END,
( SELECT t.[text]
  FROM sys.dm_exec_requests r
  CROSS APPLY sys.dm_exec_sql_text (r.sql_handle) AS t
  WHERE r.session_id = l.request_session_id
),
l.*
FROM sys.dm_tran_locks as l
JOIN sys.dm_tran_locks as l1
ON l.resource_associated_entity_id = l1.resource_associated_entity_id
WHERE l.request_status <> l1.request_status
AND
( l.resource_description = l1.resource_description OR (l.resource_description IS NULL AND l1.resource_description IS NULL)).

Filed under:
MERGE Statement in SQL Server 2008
22 July 09 08:37 PM | kasim.wirama | with no comments

MERGE Statement in SQL Server 2008

By : Kasim Wirama, MCITP, MCDBA

 

In TSQL area, SQL Server 2008 has some enhancements; one of them is ability to wrap several DML statement into one by MERGE statement. Syntax for MERGE statement is :

MERGE <target table> [AS <target table alias>]
USING <source table/query/view> [AS <source alias name>]
ON <join condition>
WHEN MATCHED THEN
    <UPDATE or DELETE statement>
WHEN NOT MATCHED BY TARGET THEN
    <INSERT statement>
WHEN NOT MATCHED BY SOURCE THEN
    <UPDATE or DELETE statement>

Example how to use MERGE statement is given below.

You have stocks stored at Stock table here :

CREATE TABLE Stock (Name varchar(10) primary key, Qty int);
GO

Insert into Stock VALUES (‘Indosat’,10000);
Insert into Stock VALUES (‘BNI’,15000);

Every day you trade stocks and those transactions are put into Trade table here :

Insert into Trade (Name varchar(10) primary key, Qty int);

For example, during a day, you sold 5000 Indosat stocks, bought 5000 BNI stocks, and bought new stocks of BPMIGAS and those are recorded into Trade table.

Insert into Trade VALUES (‘Indosat’,-5000);
Insert into Trade VALUES (‘BNI’, 5000);
Insert into Trade VALUES (‘BPMIGAS’,2000);

At the end of a day, you would like to update Stock table with transactions from Trade using MERGE statement with condition when new stock on Trade, they will be inserted into Stock table, when existing stock then they will be updated into Stock table. Here is MERGE query :

MERGE Stock AS s
USING Trade AS t
ON s.Name = t.Name
WHEN MATCHED THEN
   UPDATE SET Stock.Qty += Trade.Qty
WHEN NOT MATCHED BY TARGET THEN
   INSERT VALUES (t.Name, t.Qty);

After above MERGE statement is run, rows on Stock table will be :

Name                    Qty
Indosat                 5000
BNI                         20000
BPMIGAS            2000

You can write MERGE query here:

MERGE Stock AS s
USING Trade AS t
ON s.Name = t.Name
WHEN MATCHED THEN
   UPDATE SET Stock.Qty += Trade.Qty
WHEN NOT MATCHED THEN
   INSERT VALUES (t.Name, t.Qty);

By default if you don’t specify BY SOURCE or BY TARGET on WHEN NOT MATCHED clause, it will be default to BY TARGET.

Filed under:
Viewing Big Data in Excel 2007
21 July 09 09:43 PM | kasim.wirama | with no comments

Viewing Big Data in Excel 2007

By : Kasim Wirama, MCITP, MCDBA

 

SQL Server Integration Services (SSIS) is excellent ETL platform to do export import data from and to heterogeneous data source. In this posting, I would like to give my thought about exporting data into excel file as it is most popular alternatives besides flat file and it’s widely used as office spreadsheet application.

Excel has great feature and user friendly capability but it’s has also limitation in terms of maximum 65,536 rows supported. In SSIS 2005 it has excel provider up to version 2003 so you will get hard limit to the maximum rows and in SSIS 2008 it has excel provider up to version 2007 so you will get soft limit to the maximum rows. If you use either SSIS 2005 or SSIS 2008, you may have 2 options to export rows larger than maximum limit. First option is to create custom data source provider as SSIS provides API to extend it. Second option is to export column delimited flat files. If you frequently export big rows into excel file, I suggest you to create custom excel file extension otherwise you can have second option.

I discuss the second option. After you run export process into the delimited file; you can view them in excel 2007. Definitely excel 2003 or older version couldn’t show you whole data in one worksheet. First open your excel file. Then open tab delimited file by clicking at upper left corner and choose Open sub menu.

In open dialog menu, choose all file type and pick your column delimited file. After you click Open button, you will be presented to Text Import Wizard – Step 1 of 3. Choose Delimited option and go to Next button. On Step 2 of 3, choose delimited character and go to Next button. On last step (Step 3 of 3), you can define different data type for each column by clicking each column first and then choose data type in option region (Column Data Format).

Excel 2007 offers great flexibility than previous version. If you have big rows beyond 65,536 rows, Excel 2007 could display them perfectly.

Filed under:
SQL Server 2008 PowerShell
10 July 09 11:14 AM | kasim.wirama | with no comments

  Normal 0 false false false EN-US X-NONE X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Calibri","sans-serif";}

SQL Server 2008 PowerShell

By : Kasim Wirama, MCDBA, MCITP

PowerShell is next generation scripting language after MS-DOS. Microsoft supports software products with PowerShell. PowerShell is built on .NET 2.0 frameworks. It supports all DOS commands and could run any scripts written in other language. Here are terminology in PowerShell.

1.       CmdLet

Is command name. Naming convention for CmdLet is verb-noun. For example : get-command

 

2.       Script

PowerShell extension is ps1. To run PowerShell script, simply specify power shell scripting file.

 

3.       Pipeline

Is introduced by | sign, which separates series of commands (cmdlet). Output of current cmdlet would be input for next cmdlets.

 

4.       Provider

Is type of data store where user is presented with format similar to file system. For SQL Server provider, hierarchy SQL Server is in file system format, as you usually navigate in MS-DOS prompt.

 

5.       Snap-in

Is poweshell extension, which usually comes in DLL written in .NET programming language. Usually snap-in consists additional cmdlet or provider.

 

6.       Aliases
is shorter name of cmdlet command.

Powershell implementasion in SQL Server 2008 is called SQL Server Powershell. Command line for SQL Server 2008 PowerShell is sqlps. You can type sqlps in DOS-prompt or right click on any database object in object explorer of SSMS SQL Server 2008.

After you successfully entered into sqlps provider environment, type dir command then SQL PowerShell returns 4 items, they are : SQL Server Database Engine, SQL Server Policy Management, SQL Server Registrations, and SQL Server Data Collection. All your SQL Server instances are located inside SQL Server Database Engine. You can navigate into SQL Server Database Engine item, by issuing cd command (Cd SQL) then press enter. Then you will be presented to your machine. Your SQL instance are inside your machine name directory, so issue cd <your machine name> command. Now you are in beginning of your SQL Server instance. It displays file system hierarchy format, so it’s as convenient as navigating in DOS file system. Try yourself and tell me your experience in using SQL PowerShell.

Filed under:
Concatenate Multi Row Column Value into One Row
10 July 09 02:56 AM | kasim.wirama | with no comments

Concatenate Multi Row Column Value into One Row

By : Kasim Wirama, MCDBA, MCITP

 

Sometimes you need concatenate multiple rows into 1 string value separated by delimiter (usually comma). For example to get orderdescription from same customerid like the example below :

Declare @order table (orderid int, custid int, orderdescription varchar(50));
insert into @order values (1,676,’order by CustA’);
insert into @order values (2,676,’order by CustB’);

Expected outcome is

Order by CustA, order by CustB

SQL Server 2005 onwards comes up with XML features, one of them is FOR XML PATH, here is the query to get desired output :

Declare @list varchar(max);
set @list = stuff (
                                                (select ‘, ‘ + orderdescription as [text()]
                                                 from @order
                                                 when custid = 676
                                                 FOR XML PATH(‘’)
                                                )
                                , 1, 2, ‘’);
select @list;

It looks okay, until there is evil input into @order table like below :

insert into @order values (2,676,’order by CustA & order by CustB’);

rerun the FOR XML PATH query again, the expected outcome is

order by CustA, order by CustB, order by CustA &amp; order by CustB

If you notice ‘&’ is changed by XML PATH clause into ‘&amp;

The same thing would happen if the column value contains any HTML preserved character such as <, and >.

Better solution for reproducing single rows of concatenated values of rows is by using conventional one as following query below shown :

Declare @list varchar(max);
set @list = ‘’;
select @list =  case @list when ‘’ then orderdescription
                                              else @list + ‘, ‘ + orderdescription
                                                end
                                                 from @order
                                                 when custid = 676;

select @list;

Filed under:
More Posts