<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ralf Eisenreich &#187; sql</title>
	<atom:link href="http://sqlblog.de/blog/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://sqlblog.de/blog</link>
	<description>SQLBlog.DE &#124; ..things to remember</description>
	<lastBuildDate>Mon, 26 Dec 2011 14:37:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>SQL: Free Online ERD/DB Modeler</title>
		<link>http://sqlblog.de/blog/2011/04/sql-free-online-erddb-modeler/</link>
		<comments>http://sqlblog.de/blog/2011/04/sql-free-online-erddb-modeler/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 12:20:25 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://sqlblog.de/blog/?p=706</guid>
		<description><![CDATA[I discovered the tool WWW SQL Designer (created by Ondrej Zara) years ago and was happy to notice that it...]]></description>
			<content:encoded><![CDATA[<p>I discovered the tool <a href="http://ondras.zarovi.cz/sql/demo">WWW SQL Designer</a> (created by Ondrej Zara) years ago and was happy to notice that it still exists.<br />
Great work!</p>
<div id="attachment_707" class="wp-caption aligncenter" style="width: 310px"><img src="http://sqlblog.de/blog/wp-content/uploads/2011/04/screenshot.156-300x186.jpg" alt="SQL Online ERD/DB Modeler" title="SQL Online ERD/DB Modeler" width="300" height="186" class="size-medium wp-image-707" /><p class="wp-caption-text">SQL Online ERD/DB Modeler</p></div>
<p>[Source: http://ondras.zarovi.cz/sql/demo/]</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2011/04/sql-free-online-erddb-modeler/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SSIS: Execute Package via Stored Procedure</title>
		<link>http://sqlblog.de/blog/2009/09/ssis-execute-package-via-stored-procedure/</link>
		<comments>http://sqlblog.de/blog/2009/09/ssis-execute-package-via-stored-procedure/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 12:42:44 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://sqlblog.de/blog/?p=671</guid>
		<description><![CDATA[There are two options executing SSIS packages: - xp_cmdshell command (not recommended for security reasons) - sp_start_job command The main...]]></description>
			<content:encoded><![CDATA[<p>There are two options executing SSIS packages:</p>
<p>- <strong>xp_cmdshell</strong> command (not recommended for security reasons)<br />
- <strong>sp_start_job</strong> command</p>
<p>The main difference between both options is the execution method. The xp_cmdshell command is a <em>synchronous</em> call and the sp_start_job command is an <em>asynchronous</em> call.</p>
<p><strong>xp_cmdshell command</strong> (synchronous)</p>
<ul>
<li>enable xp_cmdshell mode in Surface Area Configuration Tool for SQL Server</li>
<li>use following procedure to execute SSIS package:<br />
<code><br />
DECLARE @returncode int<br />
EXEC @returncode = xp_cmdshell 'dtexec /f "<strong>PackageNameWithFullPath</strong>.dtsx"'<br />
</code>
</li>
</ul>
<p><strong>sp_start_job</strong> (asynchronous)</p>
<ul>
<li>define job in SQL Server Agent with SSIS execution step</li>
<li>use following procedure to start SQL Server Agent job with SSIS execution step:<br />
<code><br />
[msdb].dbo.sp_start_job @job_name='<strong>JobName</strong>'<br />
</code>
</li>
<li>check execution status of job, since the call is asynchronous:<br />
<code><br />
SELECT<br />
	[server],<br />
	[start_execution_date],<br />
	[stop_execution_date],<br />
	[run_date],<br />
	[run_duration],<br />
	[run_status],<br />
	[message]<br />
FROM<br />
	MSDB.DBO.SYSJOBS Z<br />
INNER JOIN<br />
	MSDB.DBO.SYSJOBACTIVITY A<br />
	ON Z.JOB_ID = A.JOB_ID<br />
INNER JOIN<br />
	(<br />
	SELECT<br />
		MAX(SESSION_ID) AS SESSION_ID<br />
	FROM<br />
		MSDB.DBO.SYSSESSIONS<br />
	) AS B<br />
	ON	A.SESSION_ID = B.SESSION_ID<br />
LEFT JOIN<br />
	MSDB.DBO.SYSJOBHISTORY C<br />
	ON A.JOB_HISTORY_ID = C.INSTANCE_ID<br />
WHERE<br />
	Z.NAME = '<strong>JobName</strong>'<br />
</code>
</li>
</ul>
<p>There is following way to make the call of sp_start_job synchronous.</p>
<p><strong>sp_start_job</strong> (<strong>synchronous</strong>)</p>
<ul>
<li>define job in SQL Server Agent with SSIS execution step</li>
<li>use following procedure to start SQL Server Agent job with SSIS execution step:<br />
<code><br />
ALTER PROCEDURE [dbo].[AGENT_JOB_CHECK2]<br />
-- Add the parameters for the stored procedure here<br />
DECLARE @job_name nvarchar(100)='',<br />
DECLARE @maxwaitmins int = 5<br />
AS<br />
BEGIN<br />
set NOCOUNT ON;<br />
set XACT_ABORT ON;<br />
    BEGIN TRY<br />
    declare @running as int<br />
    declare @seccount as int<br />
    declare @maxseccount as int<br />
    set @maxseccount = 60*@maxwaitmins<br />
    set @seccount = 0<br />
    set @running = 0<br />
    declare @job_owner sysname<br />
    declare @job_id UNIQUEIDENTIFIER<br />
    set @job_owner = SUSER_SNAME()<br />
    -- get job id<br />
    select @job_id=job_id<br />
    from msdb.dbo.sysjobs sj<br />
    where sj.name=@job_name<br />
    -- invalid job name then exit with an error<br />
    if @job_id is null<br />
        RAISERROR (N'Unknown job: %s.', 16, 1, @job_name)<br />
    -- output from stored procedure xp_sqlagent_enum_jobs is captured in the following table<br />
    declare @xp_results TABLE ( job_id                UNIQUEIDENTIFIER NOT NULL,<br />
                                last_run_date         INT              NOT NULL,<br />
                                last_run_time         INT              NOT NULL,<br />
                                next_run_date         INT              NOT NULL,<br />
                                next_run_time         INT              NOT NULL,<br />
                                next_run_schedule_id  INT              NOT NULL,<br />
                                requested_to_run      INT              NOT NULL, -- BOOL<br />
                                request_source        INT              NOT NULL,<br />
                                request_source_id     sysname          COLLATE database_default NULL,<br />
                                running               INT              NOT NULL, -- BOOL<br />
                                current_step          INT              NOT NULL,<br />
                                current_retry_attempt INT              NOT NULL,<br />
                                job_state             INT              NOT NULL)<br />
    -- start the job<br />
    declare @r as int<br />
    exec @r = msdb..sp_start_job @job_name<br />
    -- quit if unable to start<br />
    if @r<>0<br />
        RAISERROR (N'Could not start job: %s.', 16, 2, @job_name)<br />
    -- start with an initial delay to allow the job to appear in the job list (maybe I am missing something ?)<br />
    WAITFOR DELAY '0:0:10';<br />
    set @seccount = 10<br />
    -- check job run state<br />
    insert into @xp_results<br />
    execute master.dbo.xp_sqlagent_enum_jobs 1, @job_owner, @job_id<br />
    set @running= (SELECT top 1 running from @xp_results)<br />
    while @running<>0 and @seccount < @maxseccount<br />
    begin<br />
        WAITFOR DELAY '0:0:10';<br />
        set @seccount = @seccount + 10<br />
        delete from @xp_results<br />
        insert into @xp_results<br />
        execute master.dbo.xp_sqlagent_enum_jobs 1, @job_owner, @job_id<br />
        set @running= (SELECT top 1 running from @xp_results)<br />
    end<br />
	-- result: query<br />
	SELECT<br />
		[server],<br />
		[start_execution_date],<br />
		[stop_execution_date],<br />
		[run_date],<br />
		[run_duration],<br />
		[run_status],	-- 0: failed, 1: success, null: running<br />
		[message]<br />
	FROM<br />
		MSDB.DBO.SYSJOBS Z<br />
	INNER JOIN<br />
		MSDB.DBO.SYSJOBACTIVITY A<br />
		ON Z.JOB_ID = A.JOB_ID<br />
	INNER JOIN<br />
		(<br />
		SELECT<br />
			MAX(SESSION_ID) AS SESSION_ID<br />
		FROM<br />
			MSDB.DBO.SYSSESSIONS<br />
		) AS B<br />
		ON	A.SESSION_ID = B.SESSION_ID<br />
		LEFT JOIN<br />
		MSDB.DBO.SYSJOBHISTORY C<br />
		ON A.JOB_HISTORY_ID = C.INSTANCE_ID<br />
	WHERE Z.NAME = @job_name<br />
	-- result: not ok (=1) if still running<br />
    --if @running <> 0<br />
        --return 0<br />
    --else<br />
        --return 1<br />
    END TRY<br />
    BEGIN CATCH<br />
    DECLARE<br />
        @ErrorMessage    NVARCHAR(4000),<br />
        @ErrorNumber     INT,<br />
        @ErrorSeverity   INT,<br />
        @ErrorState      INT,<br />
        @ErrorLine       INT,<br />
        @ErrorProcedure  NVARCHAR(200);<br />
    SELECT<br />
        @ErrorNumber = ERROR_NUMBER(),<br />
        @ErrorSeverity = ERROR_SEVERITY(),<br />
        @ErrorState = ERROR_STATE(),<br />
        @ErrorLine = ERROR_LINE(),<br />
        @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');<br />
    SELECT @ErrorMessage =<br />
        N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' +<br />
            'Message: '+ ERROR_MESSAGE();<br />
    RAISERROR<br />
        (<br />
        @ErrorMessage,<br />
        @ErrorSeverity,<br />
        1,<br />
        @ErrorNumber,    -- original error number.<br />
        @ErrorSeverity,  -- original error severity.<br />
        @ErrorState,     -- original error state.<br />
        @ErrorProcedure, -- original error procedure name.<br />
        @ErrorLine       -- original error line number.<br />
        );<br />
    END CATCH<br />
END<br />
</code>
</li>
</ul>
<p>[Source: <a href="http://blog.boxedbits.com/archives/124">http://blog.boxedbits.com/archives/124</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2009/09/ssis-execute-package-via-stored-procedure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SSIS: Split Excel cell values into rows</title>
		<link>http://sqlblog.de/blog/2009/04/ssis-split-excel-cell-values-into-rows/</link>
		<comments>http://sqlblog.de/blog/2009/04/ssis-split-excel-cell-values-into-rows/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 14:26:42 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://sqlblog.de/blog/?p=474</guid>
		<description><![CDATA[Here I would like to show you a solution for following problem. One source row coming from Excel contains several...]]></description>
			<content:encoded><![CDATA[<p>Here I would like to show you a solution for following problem.<br />
One source row coming from Excel contains several values within one column. Each one of these values should be reflected in a separate row in the data destination.<br />
So the basic problem is that there we have a &#8220;list column&#8221; whose contents should be result in separate rows.</p>
<p>To make the problem more complex: The number of values in the &#8220;list column&#8221; is variable and there is a second column which contains corresponding values.</p>
<p><strong>Excel Source</strong><br />
<div id="attachment_481" class="wp-caption aligncenter" style="width: 280px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/excel_sheet.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/excel_sheet.png" alt="Excel Sheet" title="Excel Sheet" width="270" height="165" class="size-full wp-image-481" /></a><p class="wp-caption-text">Excel Sheet</p></div></p>
<p><strong>solution: SSIS Script Component</strong></p>
<p>To implement a solution for the problem we use the most adequate item &#8211; the Script Component.</p>
<ol>
<li> We start with a data flow task in our package and add an <em>OLE DB Excel Source</em> component (that returns the source data above).<br />
We can use following SQL statement:<br />
<code><br />
SELECT<br />
F1,F2,F3<br />
FROM<br />
[sheet1$B1:D5]<br />
</code><br />
The imported columns can be named as <code>KEY</code>, <code>PERSON</code>, <code>DEPARTMENT</code>.<br />
<div id="attachment_507" class="wp-caption aligncenter" style="width: 233px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/excel_source.png"><img class="size-full wp-image-507" title="Excel Source" src="http://sqlblog.de/blog/wp-content/uploads/2009/04/excel_source.png" alt="Excel Source" width="223" height="300" /></a><p class="wp-caption-text">Excel Source</p></div>
	</li>
<li> Then we add a <em>Derived Column</em> Component to the data flow as well.<br />
<div id="attachment_505" class="wp-caption aligncenter" style="width: 160px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/derived_column.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/derived_column.png" alt="Derived Column" title="Derived Column" width="150" height="131" class="size-full wp-image-505" /></a><p class="wp-caption-text">Derived Column</p></div></p>
<p>In order to replace the CRs with commas we replace the imported columns with following formula:<br />
<code><br />
REPLACE(REPLACE(REPLACE(REPLACE(PERSON,"\n",",")," ",""),",,",","),",,",",")<br />
REPLACE(REPLACE(REPLACE(REPLACE(DEPARTMENT,"\n",",")," ",""),",,",","),",,",",")<br />
</code><br />
<div id="attachment_506" class="wp-caption aligncenter" style="width: 310px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/derived_column_settings.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/derived_column_settings-300x218.png" alt="Derived Column Settings" title="Derived Column Settings" width="300" height="218" class="size-medium wp-image-506" /></a><p class="wp-caption-text">Derived Column Settings</p></div>
	</li>
<li>
As result we receive following list of elements:</p>
<ul>
<li> &#8211; -</li>
<li><em>row 1</em></li>
<li>PERSON: Mr. Wayne,Mr. Kent,Mr. Parker</li>
<li>DEPARTMENT: Heros/Batman,Heros/Superman,Heros/Spiderman</li>
<li> &#8211; -</li>
<li><em>row 2</em></li>
<li>PERSON: Mr. Kirk,Ms. Janeway</li>
<li>DEPARTMENT: StarTrek/Classic,StartTrek/Voyager</li>
<li> &#8211; -</li>
<li><em>row 3</em></li>
<li>PERSON: &#8220;Mr. Wrong&#8221;</li>
<li>DEPARTMENT: Wrong entry 1,Wrong entry 2</li>
<li> &#8211; -</li>
</ul>
</li>
<li> Now we add a Script Component to the data flow.<br />
When we are prompted to select the type of the component we choose <em>Transformation</em>.</p>
<p><div id="attachment_508" class="wp-caption aligncenter" style="width: 168px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component.png" alt="Script Component" title="Script Component" width="158" height="232" class="size-full wp-image-508" /></a><p class="wp-caption-text">Script Component</p></div>
	</li>
<li> Then we right-click on the <em>Script Component</em> and choose Edit. In the Script Transformation Editor dialog box we select all three columns to make them available as input columns. Now these column are available in the Script code.<br />
<div id="attachment_516" class="wp-caption aligncenter" style="width: 310px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_columns.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_columns-300x260.png" alt="Script Component Columns" title="Script Component Columns" width="300" height="260" class="size-medium wp-image-516" /></a><p class="wp-caption-text">Script Component Columns</p></div>
	</li>
<li> Since the tranformation is going to produce more output rows than it receives input rows we have to mark the transformation as asynchronous. This is done by setting the <em>SynchronousInputID</em> property of the output to <em>None</em>.<br />
<div id="attachment_511" class="wp-caption aligncenter" style="width: 310px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_settings.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_settings-300x212.png" alt="Script Component Settings" title="Script Component Settings" width="300" height="212" class="size-medium wp-image-511" /></a><p class="wp-caption-text">Script Component Settings</p></div>
	</li>
<li> Next, we have to specify the output columns that the output buffer will contain. So we select the transformation&#8217;s output and click <em>Add Column</em> and set the properties (column name and data type).<br />
<div id="attachment_510" class="wp-caption aligncenter" style="width: 310px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_input.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_input-300x256.png" alt="Script Component Input / Output rows" title="Script Component Input / Output rows" width="300" height="256" class="size-medium wp-image-510" /></a><p class="wp-caption-text">Script Component Input / Output rows</p></div>
	</li>
<li>
Now we can add the code by clicking on the <em>Design Script button</em>.<br />
<div id="attachment_509" class="wp-caption aligncenter" style="width: 295px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_design.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/script_component_design.png" alt="Script Component - Design Script" title="Script Component - Design Script" width="285" height="183" class="size-full wp-image-509" /></a><p class="wp-caption-text">Script Component - Design Script</p></div>
	</li>
<li>
Following Code is splitting our list of items into rows:<br />
<code><br />
' Variables<br />
Dim i As Integer = 0<br />
Dim itemList_PERSON As String = Row.PERSON<br />
Dim itemList_DEPARTMENT As String = Row.DEPARTMENT<br />
Dim delimiter As String = ','<br />
If Not (String.IsNullOrEmpty(itemList_PERSON) Or String.IsNullOrEmpty(itemList_DEPARTMENT)) Then<br />
Dim inputListArray_Wer() As String = itemList_PERSON.Split(New String() {delimiter}, StringSplitOptions.RemoveEmptyEntries)<br />
Dim inputListArray_Abt() As String = itemList_DEPARTMENT.Split(New String() {delimiter}, StringSplitOptions.RemoveEmptyEntries)<br />
If (inputListArray_Wer.Length = inputListArray_Abt.Length) Then<br />
' new rows<br />
For Each item As String In inputListArray_Wer<br />
With Output0Buffer<br />
.AddRow()<br />
.KEY = CInt(Row.KEY)<br />
.PERSON = item<br />
.DEPARTMENT = inputListArray_Abt(i).ToString()<br />
End With<br />
' increase counter<br />
i = i + 1<br />
Next<br />
Else<br />
' Filtered Rows<br />
With Output1Buffer<br />
.AddRow()<br />
.KEY = CInt(Row.KEY)<br />
.PERSON = Row.PERSON<br />
.DEPARTMENT = Row.DEPARTMENT<br />
End With<br />
End If<br />
End If<br />
</code><br />
The code shows that there are two outputs. Whenever a record set cannot be split or the columns <em>PERSON</em> and <em>DEPARTMENT</em> have a different number of itemss the rows is redirected to the second output (here <em>Output1</em>).
	</li>
<li>
In order to receive the output from the Script Component we add a <em>Union All Component</em>. Additionally we add two <em>Data Viewer Components</em>, since  we want to see the resulting outputs from the Script Component.<br />
<div id="attachment_502" class="wp-caption aligncenter" style="width: 295px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_flow_union_all.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_flow_union_all-285x300.png" alt="Union ALL" title="Union ALL" width="285" height="300" class="size-medium wp-image-502" /></a><p class="wp-caption-text">Union ALL</p></div>
	</li>
<li>
Running the SSIS package will bring the following result.<br />
<div id="attachment_501" class="wp-caption aligncenter" style="width: 290px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_flow_complete.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_flow_complete-280x300.png" alt="Data Flow completed" title="Data Flow completed" width="280" height="300" class="size-medium wp-image-501" /></a><p class="wp-caption-text">Data Flow completed</p></div>
	</li>
<li>
As we can see, the first DataViewer Component show us the <em>valid</em> rows produced by our Script Component.<br />
<div id="attachment_504" class="wp-caption aligncenter" style="width: 310px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_viewer_valid.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_viewer_valid-300x120.png" alt="Data Viewer valid rows" title="Data Viewer valid rows" width="300" height="120" class="size-medium wp-image-504" /></a><p class="wp-caption-text">Data Viewer valid rows</p></div>
	</li>
<li>
The second DataViewer Component show us the <em>invalid</em> rows produced by our Script Component.<br />
<div id="attachment_503" class="wp-caption aligncenter" style="width: 310px"><a href="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_viewer_invalid.png"><img src="http://sqlblog.de/blog/wp-content/uploads/2009/04/data_viewer_invalid-300x35.png" alt="Data Viewer invalid rows" title="Data Viewer invalid rows" width="300" height="35" class="size-medium wp-image-503" /></a><p class="wp-caption-text">Data Viewer invalid rows</p></div>
	</li>
</ol>
<p><strong>download</strong><br />
Of course I provide you the solution as <a href='http://sqlblog.de/blog/wp-content/uploads/2009/04/excel_split_column.zip'>download</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2009/04/ssis-split-excel-cell-values-into-rows/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>T-SQL: Split column in several rows</title>
		<link>http://sqlblog.de/blog/2009/04/t-sql-split-column-in-several-rows/</link>
		<comments>http://sqlblog.de/blog/2009/04/t-sql-split-column-in-several-rows/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 14:10:39 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[snippets]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://sqlblog.de/blog/?p=550</guid>
		<description><![CDATA[problem If I have a column with several values (separated by CR) which I need separated into rows then following...]]></description>
			<content:encoded><![CDATA[<p><strong>problem</strong><br />
If I have a column with several values (separated by CR) which I need separated into rows then following solution can help:</p>
<p><strong>possible solution: T-SQL</strong><br />
One possible solution using T-SQL is following statement.<br />
The function <code>fn_Split</code> returns all values in a list and the <code>replace</code> function converts the CR (carriage returns) to commas.</p>
<p><code><br />
SELECT<br />
[Key]<br />
,[b.Value]<br />
,[c.Value]<br />
FROM<br />
[dbo.TableExcel] AS a<br />
CROSS APPLY<br />
fn_Split(REPLACE(a.Persons, CHAR(10)+CHAR(13),','), ',') AS b<br />
CROSS APPLY<br />
fn_Split(REPLACE(a.Departments, CHAR(10)+CHAR(13),','), ',') AS c<br />
</code></p>
<p>The corresponding <code>fn_Split</code> function:<br />
<code><br />
CREATE FUNCTION [dbo].[fn_Split](@text nvarchar(max), @delimiter char(1) = ' ')<br />
RETURNS @Strings TABLE (<br />
position int IDENTITY PRIMARY KEY,<br />
value nvarchar(max)<br />
)<br />
AS<br />
BEGIN<br />
DECLARE @index int<br />
SET @index = -1<br />
WHILE (LEN(@text) &gt; 0)<br />
BEGIN<br />
SET @index = CHARINDEX(@delimiter , @text)<br />
IF (@index = 0) AND (LEN(@text) &gt; 0)<br />
BEGIN<br />
INSERT INTO @Strings VALUES (@text)<br />
BREAK<br />
END<br />
IF (@index &gt; 1)<br />
BEGIN<br />
INSERT INTO @Strings<br />
VALUES (LEFT(@text, @index - 1))<br />
SET @text = RIGHT(@text, (LEN(@text) - @index))<br />
END<br />
ELSE<br />
SET @text = RIGHT(@text, (LEN(@text) - @index))<br />
END<br />
RETURN<br />
END<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2009/04/t-sql-split-column-in-several-rows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSIS: Excel Import Column Data Types</title>
		<link>http://sqlblog.de/blog/2009/04/ssis-excel-import-column-data-types/</link>
		<comments>http://sqlblog.de/blog/2009/04/ssis-excel-import-column-data-types/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 08:39:59 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://sqlblog.de/blog/?p=428</guid>
		<description><![CDATA[When Excel data is not coming into SSIS right, then do the following: use option &#8220;IMEX=1&#8221; in ConnectionString (Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\..\MyExcel.xls;Extended...]]></description>
			<content:encoded><![CDATA[<p>When Excel data is not coming into SSIS right, then do the following:</p>
<ol>
<li>use option &#8220;<code>IMEX=1</code>&#8221; in ConnectionString (<code>Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\..\MyExcel.xls;Extended Properties="Excel 8.0;HDR=Yes;IMEX=1"</code>)</li>
<li>modify registry setting &#8220;<code>TypeGuessRows=8</code>&#8221; to a much higher value</li>
<li>use a sql statement to retrieve data (e.g. &#8220;<code>SELECT * FROM [sheet1$A5:M2000]</code>&#8220;)</li>
</ol>
<p>NOTE: The setting <code>IMEX=1</code> tells the Excel driver to use <em>Import</em> mode. This mode reads the registry setting &#8220;<code>ImportMixedTypes=Text</code>&#8221; which forces mixed data to be converted to text. To achieve a more reliable column type recognition, the registry setting &#8220;<code>TypeGuessRows=8</code>&#8221; should be increased. By default the ISAM driver analyzes  the first eight rows and determines the column datatypes from this sampling. If the first analysed rows contain only numeric values, then setting <code>IMEX=1</code> will not convert this column datatype to Text &#8211; it will remain numeric.</p>
<p>ATTENTION: The IMEX setting has some other modes:</p>
<ul>
<li>0 is Export mode</li>
<li>1 is Import mode</li>
<li>2 is Linked mode (full update capabilities)</li>
</ul>
<p>Registry Setting Location:<br />
<code><br />
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\X.X\Engines\Excel<br />
</code></p>
<p><strong>supplement</strong><br />
If you experience following error the above described solution could fix it.<br />
1. An OLE DB error has occurred. Error code: 0x80040E21.<br />
2. Failed to retrieve long data for column &#8220;XYZ&#8221;.<br />
3. There was an error with output column &#8220;XYZ&#8221; (55488) on output &#8220;Excel Source Output&#8221; (109). The column status returned was: &#8220;DBSTATUS_UNAVAILABLE&#8221;.<br />
4. The &#8220;output column &#8220;XYZ&#8221;  (55488)&#8221; failed because error code 0xC0209071 occurred, and the error row disposition on &#8220;output column &#8220;XYZ&#8221; (55488)&#8221; specifies failure on error. An error occurred on the specified object of the specified component.<br />
5. [DTS.Pipeline] Error: The PrimeOutput method on component &#8220;Info Source&#8221; (101) returned error code 0xC0209029.  The component returned a failure code when the pipeline engine called PrimeOutput(). The meaning of the failure code is defined by the component, but the error is fatal and the pipeline stopped executing.<br />
6. [DTS.Pipeline] Error: Thread &#8220;SourceThread0&#8243; has exited with error code 0xC0047038. </p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2009/04/ssis-excel-import-column-data-types/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQL Server: Version, Service Pack, Edition</title>
		<link>http://sqlblog.de/blog/2009/03/sql-server-version-service-pack/</link>
		<comments>http://sqlblog.de/blog/2009/03/sql-server-version-service-pack/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 08:59:06 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://sqlblog.de/blog/?p=413</guid>
		<description><![CDATA[SQL Server: Version, Service Pack, Edition Just run following command within Management Studio: SELECT @@VERSION, SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')...]]></description>
			<content:encoded><![CDATA[<p><strong>SQL Server: Version, Service Pack, Edition</strong></p>
<p>Just run following command within Management Studio:<br />
<code>SELECT<br />
 @@VERSION,<br />
 SERVERPROPERTY('productversion'),<br />
 SERVERPROPERTY ('productlevel'),<br />
 SERVERPROPERTY ('edition')</code></p>
<p>As result you receive something like:</p>
<pre class="code">Microsoft SQL Server 2005 - ... Windows NT 5.2 (Build 3790: SP 2)
  9.00.4035.00
  SP3
  Standard Edition (64-bit)</pre>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2009/03/sql-server-version-service-pack/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>INSERT INTO.. aus SELECT</title>
		<link>http://sqlblog.de/blog/2006/08/insert-into-aus-select/</link>
		<comments>http://sqlblog.de/blog/2006/08/insert-into-aus-select/#comments</comments>
		<pubDate>Thu, 10 Aug 2006 06:43:18 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.ralf-eisenreich.de/blog/index.php/2006/08/10/insert-into-aus-select/</guid>
		<description><![CDATA[Mit folgender SQL-Abfrage kann man in ein &#8220;INSERT INTO&#8221; ein SELECT Statement einbauen: INSERT INTO table1 (column1, column2) VALUES(@parameter1, (SELECT...]]></description>
			<content:encoded><![CDATA[<p>Mit folgender SQL-Abfrage kann man in ein &#8220;INSERT INTO&#8221; ein SELECT Statement einbauen:</p>
<p><code>INSERT INTO <em>table1</em> (<em>column1</em>, <em>column2</em>)<br />
VALUES(<em>@parameter1</em>, (SELECT <em>columnX</em> FROM <em>table2</em><br />
WHERE <em>columnY</em> = '<em>@parameter2</em>'))</code></p>
<p>oder</p>
<p><code>INSERT INTO <em>table1</em> (<em>column1</em>, <em>column2</em>)<br />
SELECT <em>@parameter1</em>, columnX FROM <em>table2</em><br />
WHERE <em>columnY</em> = '<em>@parameter2</em>'</code></p>
<p>Quelle: [<a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=5969">SQLTeam</a>] und [<a href="http://www.ive-blaschke.de/">Ive</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2006/08/insert-into-aus-select/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MS Access: Multiselect in Queries</title>
		<link>http://sqlblog.de/blog/2006/04/ms-access-multiselect-in-queries/</link>
		<comments>http://sqlblog.de/blog/2006/04/ms-access-multiselect-in-queries/#comments</comments>
		<pubDate>Sat, 08 Apr 2006 15:45:43 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[access]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://ralf-eisenreich.de/blog/index.php/2006/04/08/ms-access-multiselect-in-queries/</guid>
		<description><![CDATA[In MS Access verwendet man in den Benutzerschnittstellen gern Listen mit Multiselect-Funktion, um dem Anwender flexiblere AuswahlmÃ¶glichkeiten zu bieten. In...]]></description>
			<content:encoded><![CDATA[<p>In MS Access verwendet man in den Benutzerschnittstellen gern Listen mit Multiselect-Funktion, um dem Anwender flexiblere AuswahlmÃ¶glichkeiten zu bieten.</p>
<p>In Queries ist es jedoch etwas schwierig diese Optionen abzufragen. Folgende VBA-Funktion schafft da Abhilfe:<br />
<code><br />
Function InMultiSelect(frms, ctrl As String, col As Integer, data As Variant, ParamArray OtherArgs()) As Boolean<br />
'Checks whether a Variant (data or OtherArgs) is included in the specified column (col) of a ListBox (ctrl)<br />
'in a certain Form (frms)<br />
On Error GoTo Error_InMultiSelect<br />
Dim varItm As Variant<br />
Dim index As Integer<br />
Dim ctl As Control<br />
Dim frm As Form<br />
Set frm = Forms(frms)<br />
Set ctl = frm.Controls(ctrl)<br />
InMultiSelect = False<br />
For Each varItm In ctl.ItemsSelected<br />
If InMultiSelect = True Then Exit For<br />
If CStr(data) = CStr(ctl.Column(col, varItm)) Then InMultiSelect = True<br />
For index = LBound(OtherArgs) To UBound(OtherArgs)<br />
If InMultiSelect = True Then Exit For<br />
If CStr(OtherArgs(index)) = CStr(ctl.Column(col, varItm)) Then InMultiSelect = True<br />
Next index<br />
Next varItm<br />
Exit Function<br />
Error_InMultiSelect:<br />
InMultiSelect = False<br />
Exit Function<br />
End Function<br />
</code></p>
<p>In den Abfragen (Queries) selbst wird diese Funktion dann beispielsweise so aufgerufen:</p>
<p><code><br />
SELECT *<br />
FROM [tblTabelle]<br />
WHERE InMultiSelect("[frmFormMitMultiSelectAuswahl]","[lstListeMitMultiSelectAuswahl]",0,[tblTabelle].[Spalte]))&lt;&gt;False);<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2006/04/ms-access-multiselect-in-queries/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>MS Access: IF EXISTS DROP TABLE</title>
		<link>http://sqlblog.de/blog/2006/04/ms-access-if-exists-drop-table/</link>
		<comments>http://sqlblog.de/blog/2006/04/ms-access-if-exists-drop-table/#comments</comments>
		<pubDate>Sat, 08 Apr 2006 15:20:30 +0000</pubDate>
		<dc:creator>Ralf</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[access]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://ralf-eisenreich.de/blog/index.php/2006/04/08/ms-access-if-exists-drop-table/</guid>
		<description><![CDATA[Leider ist es in MS Access nicht ohne weiteres möglich das Vorhandensein einer Tabelle abzufragen. Dies wird gerade wenn man...]]></description>
			<content:encoded><![CDATA[<p>Leider ist es in MS Access nicht ohne weiteres möglich das Vorhandensein einer Tabelle abzufragen.</p>
<p>Dies wird gerade wenn man mit temporÃ¤ren Tabellen arbeitet zum Problem.</p>
<p>Eine Abhilfe liefert folgende VBA-Funktion:<br />
<code><br />
' check if a table exists<br />
Function tableExists(tableName As String) As Boolean<br />
On Error GoTo Error_tableExists<br />
Dim strTableName<br />
' assign tableName to String<br />
strTableName = CurrentDb.TableDefs(tableName)<br />
' if no error occurs then set tableExists to true<br />
tableExists = True<br />
Exit_tableExists:<br />
On Error Resume Next<br />
Exit Function<br />
Error_tableExists:<br />
Select Case Err.Number<br />
Case 3265  'Item not found in this collection<br />
tableExists = False<br />
Resume Exit_tableExists<br />
Case Else<br />
MsgBox "Error " &#038; Err.Number &#038; ": " &#038; Err.Description, vbCritical<br />
Resume Exit_tableExists<br />
End Select<br />
End Function<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://sqlblog.de/blog/2006/04/ms-access-if-exists-drop-table/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

