Showing posts with label plan. Show all posts
Showing posts with label plan. Show all posts

Wednesday, March 28, 2012

How to establish connection between SQL Server database & VWD 2005

I just got a shared hosting plan with godaddy (economy plan) ...

I wrote a simple application with a database. it works fine on my local PC.

I tried to upload my files to the server, but i couldn't get database file on godaddy's server. I did a little research and found out they dont allow uploading database files to their server nor they allow remote access either.

so I logged in to my account and found a database links and I created one (SQL Server)

Host Namewhsql-v44.prod.mesa4.secureserver.netDatabase NameDB_43434Database Version2000Descriptionmaindb

I then logged in to the database and created a new table .. but now I dont know how to make a connection between this database and my application on my pc.

I later found that I must modify my web.config file for the database to work.
http://help.godaddy.com/article.php?article_id=689&topic_id=216&prog_id=GoDaddy&isc=

<connectionStrings
<add name="Personal" connectionString="
Server=whsql-v04.prod.mesa1.secureserver.net;
Database=DB_675;
User ID=user_id;
Password=password;
Trusted_Connection=False" providerName="System.Data.SqlClient" />
<remove name="LocalSqlServer"/
<add name="LocalSqlServer" connectionString="
Server=whsql-v04.prod.mesa1.secureserver.net;
Database=DB_675;
User ID=user_id;
Password=password;
Trusted_Connection=False" providerName="System.Data.SqlClient" /
</connectionStrings>


Now- I am new to web developing, but I do understand that this code is not enough to create the connection to the database. I researched alot but I cant get further.

What code/ settings/ steps do I need to do to get my gridview and other database items connect to the database on godaddy's server ?

any help would be greatly appreciated...

I think that connection string is all you need to make your web page working. You only have to create on your host SQL server the same database structure you have on your local PC, remember about users and user rights. If you use Microsoft web form security you also have to create security database on you remote server.

How to enforce SQL Server 2005 to use Worktable?

I have a problem in SQL Server 2005. In some cases SQL Server produces an execution plan of complex query (8 joins of views, some of views contains couple of joins) which does not contain a woktable creation in tempdb. As a result time of query execution increasion for about 5 seconds to about 4 minutes. All necessary indexes are created. It sims all data located in cache. Is there any way to enforce SQL Server to create worktable?

Query

SELECT [a0].[id],[a0].[Priority],[a0].[Heading],[a0].[DocumentDate],[a0].[LastName],[a0].[FirstName],[a2].[Name],[a1].[Position],[a4].[ContactTime],[a4].[Subject],[a0].[WorkPhone],[a0].[MobilePhone],[a0].[FaxNumber],[a0].[PrimaryEmail],[a5].[ContactTime],[a6].[Value],[a7].[id],[a7].[id_class],[a8].[id],[a8].[id_class],[a0].[FIO]
FROM [Bkc_EBM_Person_View] [a0]
LEFT JOIN [Bkc_EBM_ContactsInfo_View] [a3] ON ( a0.ContactsInfo_id = a3.[id] )
LEFT JOIN [Bkc_EBM_Contact_View] [a4] ON ( a3.LastContact_id = a4.[id] )
LEFT JOIN [Bkc_EBM_Contact_View] [a5] ON ( a3.NextContact_id = a5.[id] )
LEFT JOIN [Bkc_EBM_PersonType_View] [a6] ON ( a0.PersonType_id = a6.[id] )
LEFT JOIN [Bkc_EBM_Employment_View] [a1] ON ( a0.PrimaryEmployment_id = a1.[id] )
LEFT JOIN [Bkc_EBM_Client_View] [a2] ON ( a1.Client_id = a2.[id] )
LEFT JOIN [Bkc_EBM_Person_View] [a7] ON ( a0.Responsible_id = a7.[id] )
LEFT JOIN [Bkc_EBM_Department_View] [a8] ON ( a0.Department_id = a8.[id] )

Statistics

(2454 row(s) affected)

Table 'ReadRights'. Scan count 2455, logical reads 109411, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'ProcessAccounts'. Scan count 11102, logical reads 22266, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Department'. Scan count 0, logical reads 4908, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Person'. Scan count 0, logical reads 38986, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Client'. Scan count 0, logical reads 4826, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Employment'. Scan count 0, logical reads 83632238, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_PersonType'. Scan count 0, logical reads 4908, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Contact'. Scan count 0, logical reads 9816, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_ContactsInfo'. Scan count 0, logical reads 4908, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

SQL Server Execution Times:

CPU time = 231719 ms,elapsed time = 253491 ms.

Execution plan

http://rsdn.ru/File/22090/plan1.rar

Please post the view definitions.

It looks like your view definition for BKc_EBM_Employment has a bad join in it, You are processing 640Gb of data from the BKcEBM_Employment table

|||try forcing a recompile.

e.g.
select *
from ...
option (recompile)|||

Below is the view definition

Bkc_EBM_Employment is a table which connects Bkc_EBM_Person and Bkc_EBM_Client in a many-to-many relation.

ReadRights is a table which defines rights of user account to view particular document in system

processaccounts is a table, to which Application server writes corrspondence between current spid and user account id, before executing a query

USE [Oblik_CRM]

GO

/****** Object: View [dbo].[Bkc_EBM_Employment_View] Script Date: 10/04/2006 10:18:38 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE VIEW [dbo].[Bkc_EBM_Employment_View] WITH SCHEMABINDING AS

(SELECT [id], 1370 AS [id_class], cast([id] as varchar(64))+'_1370' AS [id_record], t.[EmployedPerson_id], t.[EmployedPerson_class_id], t.[Client_id], t.[Client_class_id], t.[Department_id], t.[Department_class_id], t.[Position], t.[PlaceOfWorkType_id], t.[PlaceOfWorkType_class_id], t.[RoleEmployee_id], t.[RoleEmployee_class_id], t.[FRC_id], t.[FRC_class_id], t.[InnerPhone], t.[IsPrimary], t.[IsFired], t.[EmploymentDate], t.[FiredDate], t.[FiredReason_id], t.[FiredReason_class_id], t.[Description], t.[RightToSign], t.[Heading], t.[Version] FROM dbo.Bkc_EBM_Employment t

inner join dbo.ReadRights r on (t.EmployedPerson_id = r.object_id) inner join dbo.ProcessAccounts pa WITH (NOLOCK) on (r.account_id = pa.account_id) where pa.spid=@.@.spid

)

|||

I rewrite the query without using viws. It helps a little because in new query data, that not needed by this query not queried by the views. But time of query execution is still to long. About 2 minutes

declare @.userID int

set @.userID = 104356

declare @.qp_0 int

set @.qp_0 = 0

DELETE ProcessAccounts WITH (ROWLOCK) WHERE spid=@.@.spid INSERT ProcessAccounts WITH (ROWLOCK) (account_id, spid) VALUES (@.userID, @.@.spid)

SELECT

[a0].[id],[a0].[Heading],[a0].[DocumentDate],[a0].[DocumentId],[a0].[Name],[a0].[PrimaryPhone],[a0].[PrimaryEmail],

[a1].[FIO],

[a3].[ContactTime],

[a4].[WorkPhone],[a4].[WorkEmail],[a4].[FIO],

[a5].[Value],

[a6].[Position],

[a7].[ContactTime]

FROM

(

SELECT [a0].[id],[a0].[Heading],[a0].[DocumentDate],[a0].[DocumentId],[a0].[Name],[a0].[PrimaryPhone],[a0].[PrimaryEmail], a0.Responsible_id, a0.ClientType_id, a0.ContactsInfo_id, a0.IsTemplate FROM [Bkc_EBM_Client] [a0]

INNER JOIN [ReadRights] [a0r] ON ([a0].[id] = [a0r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a0pa] ON ( [a0r].[account_id] = [a0pa].[account_id] )

) [a0]

LEFT JOIN [Bkc_EBM_ClientType] [a5] ON ( a0.ClientType_id = a5.[id] )

LEFT JOIN

(

SELECT [a1].[id], [a1].[FIO] FROM [Bkc_EBM_Person] [a1]

INNER JOIN [ReadRights] [a1r] ON ([a1].[id] = [a1r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a1pa] ON ( [a1r].[account_id] = [a1pa].[account_id] )

) [a1] ON ( a0.Responsible_id = a1.[id] )

LEFT JOIN [Bkc_EBM_ContactsInfo] [a2] ON ( a0.ContactsInfo_id = a2.[id] )

LEFT JOIN

(

SELECT [a3].[id], [a3].[ContactTime] FROM [Bkc_EBM_Contact] [a3]

INNER JOIN [ReadRights] [a3r] ON ([a3].[id] = [a3r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a3pa] ON ( [a3r].[account_id] = [a3pa].[account_id] )

) [a3] ON ( a2.LastContact_id = a3.[id] )

LEFT JOIN

(

SELECT [a4].[id], [a4].[WorkPhone],[a4].[WorkEmail],[a4].[FIO], [a4].[PrimaryEmployment_id] FROM [Bkc_EBM_Person] [a4]

INNER JOIN [ReadRights] [a4r] ON ([a4].[id] = [a4r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a4pa] ON ( [a4r].[account_id] = [a4pa].[account_id] )

) [a4] ON ( a2.LastContactPerson_id = a4.[id] )

LEFT JOIN

(

SELECT [a6].[id], [a6].[Position] FROM [Bkc_EBM_Employment] [a6]

INNER JOIN [ReadRights] [a6r] ON ([a6].[EmployedPerson_id] = [a6r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a6pa] ON ( [a6r].[account_id] = [a6pa].[account_id] )

) [a6] ON ( a4.PrimaryEmployment_id = a6.[id] )

LEFT JOIN

(

SELECT [a7].[id], [a7].[ContactTime] FROM [Bkc_EBM_Contact] [a7]

INNER JOIN [ReadRights] [a7r] ON ([a7].[id] = [a7r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a7pa] ON ( [a7r].[account_id] = [a7pa].[account_id] )

) [a7] ON ( a2.NextContact_id = a7.[id] )

WHERE ([a0].[IsTemplate] = @.qp_0 OR [a0].[IsTemplate] IS NULL )

DELETE ProcessAccounts WITH (ROWLOCK) WHERE spid=@.@.spid

Statistics

(1750 row(s) affected)

Table 'ReadRights'. Scan count 5891, logical reads 222578, physical reads 425, read-ahead reads 283, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'ProcessAccounts'. Scan count 6, logical reads 5891, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Contact'. Scan count 0, logical reads 7000, physical reads 98, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Employment'. Scan count 0, logical reads 33686288, physical reads 33, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Person'. Scan count 0, logical reads 7000, physical reads 60, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_ContactsInfo_View'. Scan count 0, logical reads 3500, physical reads 5, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_ClientType_View'. Scan count 0, logical reads 3500, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Client'. Scan count 0, logical reads 33252, physical reads 43, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

SQL Server Execution Times:

CPU time = 111797 ms, elapsed time = 123889 ms.

Execution Plan

http://rsdn.ru/File/22090/plan4.rar

|||

Please post the scripts for all the tables involved and indexes.

To get performance you need to reduce the amount of data being read from Bkc_EBM_Employment

|||Do you have a where clause on your query ?|||

SimonS_ wrote:

Do you have a where clause on your query ?

Yes "WHERE ([a0].[IsTemplate] = @.qp_0 OR [a0].[IsTemplate] IS NULL ) " (see query in the answer above) but there is no records in database filtered by this condition.

About database

'ReadRights' ~ 500000 records
'ProcessAccounts' 1 record
'Bkc_EBM_Person' ~ 2500 records
'Bkc_EBM_Client' ~ 1700 records
'Bkc_EBM_ClientType' ~ 20 records
'Bkc_EBM_ContactsInfo' ~ 4000 records
'Bkc_EBM_Contact' ~ 5000 records
'Bkc_EBM_Employment' ~ 2500 records

Very strange, but it sims RECOMPILE option helps. Worktable is created even right after SQL Server restart. If RECOMPLIE not used after server restart Worktable not created.

|||

The problem is query plans. Your query won't change from one user to the next or from one template to the next however this means the same query plan will be used. However the same query plan will not be optimal for all situations.

What can happen is that a plan is put in the cache based on the first set of parameters supplied, if this plan is not suitable for all queries you can end up with the problem above.

The recompile will address this at the expense of having to compile the query every time.

|||

Thank you for your help Simon. RECOMPILE is really helps.

Maybe in my case using of parameters in a query is not the best choise? Especially @.userID ?

|||Can you still post the CREATE table statements and CREATE View statements so I can understand your query better, its quite difficult with your use of views to understand what is joining to what.|||

Script will be quite large. Maybe by email?

|||try SQLForumsATonarcDOTcom|||I send the script. Please check.|||Another problem. In SQL Server 2000 option (recompile) is not supported. Is there any way to enforce SQL Server 2000 to recompile execution plan every time?

How to enforce SQL Server 2005 to use Worktable?

I have a problem in SQL Server 2005. In some cases SQL Server produces an execution plan of complex query (8 joins of views, some of views contains couple of joins) which does not contain a woktable creation in tempdb. As a result time of query execution increasion for about 5 seconds to about 4 minutes. All necessary indexes are created. It sims all data located in cache. Is there any way to enforce SQL Server to create worktable?

Query

SELECT [a0].[id],[a0].[Priority],[a0].[Heading],[a0].[DocumentDate],[a0].[LastName],[a0].[FirstName],[a2].[Name],[a1].[Position],[a4].[ContactTime],[a4].[Subject],[a0].[WorkPhone],[a0].[MobilePhone],[a0].[FaxNumber],[a0].[PrimaryEmail],[a5].[ContactTime],[a6].[Value],[a7].[id],[a7].[id_class],[a8].[id],[a8].[id_class],[a0].[FIO]
FROM [Bkc_EBM_Person_View] [a0]
LEFT JOIN [Bkc_EBM_ContactsInfo_View] [a3] ON ( a0.ContactsInfo_id = a3.[id] )
LEFT JOIN [Bkc_EBM_Contact_View] [a4] ON ( a3.LastContact_id = a4.[id] )
LEFT JOIN [Bkc_EBM_Contact_View] [a5] ON ( a3.NextContact_id = a5.[id] )
LEFT JOIN [Bkc_EBM_PersonType_View] [a6] ON ( a0.PersonType_id = a6.[id] )
LEFT JOIN [Bkc_EBM_Employment_View] [a1] ON ( a0.PrimaryEmployment_id = a1.[id] )
LEFT JOIN [Bkc_EBM_Client_View] [a2] ON ( a1.Client_id = a2.[id] )
LEFT JOIN [Bkc_EBM_Person_View] [a7] ON ( a0.Responsible_id = a7.[id] )
LEFT JOIN [Bkc_EBM_Department_View] [a8] ON ( a0.Department_id = a8.[id] )

Statistics

(2454 row(s) affected)

Table 'ReadRights'. Scan count 2455, logical reads 109411, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'ProcessAccounts'. Scan count 11102, logical reads 22266, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Department'. Scan count 0, logical reads 4908, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Person'. Scan count 0, logical reads 38986, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Client'. Scan count 0, logical reads 4826, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Employment'. Scan count 0, logical reads 83632238, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_PersonType'. Scan count 0, logical reads 4908, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Contact'. Scan count 0, logical reads 9816, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_ContactsInfo'. Scan count 0, logical reads 4908, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

SQL Server Execution Times:

CPU time = 231719 ms,elapsed time = 253491 ms.

Execution plan

http://rsdn.ru/File/22090/plan1.rar

Please post the view definitions.

It looks like your view definition for BKc_EBM_Employment has a bad join in it, You are processing 640Gb of data from the BKcEBM_Employment table

|||try forcing a recompile.

e.g.
select *
from ...
option (recompile)|||

Below is the view definition

Bkc_EBM_Employment is a table which connects Bkc_EBM_Person and Bkc_EBM_Client in a many-to-many relation.

ReadRights is a table which defines rights of user account to view particular document in system

processaccounts is a table, to which Application server writes corrspondence between current spid and user account id, before executing a query

USE [Oblik_CRM]

GO

/****** Object: View [dbo].[Bkc_EBM_Employment_View] Script Date: 10/04/2006 10:18:38 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE VIEW [dbo].[Bkc_EBM_Employment_View] WITH SCHEMABINDING AS

(SELECT [id], 1370 AS [id_class], cast([id] as varchar(64))+'_1370' AS [id_record], t.[EmployedPerson_id], t.[EmployedPerson_class_id], t.[Client_id], t.[Client_class_id], t.[Department_id], t.[Department_class_id], t.[Position], t.[PlaceOfWorkType_id], t.[PlaceOfWorkType_class_id], t.[RoleEmployee_id], t.[RoleEmployee_class_id], t.[FRC_id], t.[FRC_class_id], t.[InnerPhone], t.[IsPrimary], t.[IsFired], t.[EmploymentDate], t.[FiredDate], t.[FiredReason_id], t.[FiredReason_class_id], t.[Description], t.[RightToSign], t.[Heading], t.[Version] FROM dbo.Bkc_EBM_Employment t

inner join dbo.ReadRights r on (t.EmployedPerson_id = r.object_id) inner join dbo.ProcessAccounts pa WITH (NOLOCK) on (r.account_id = pa.account_id) where pa.spid=@.@.spid

)

|||

I rewrite the query without using viws. It helps a little because in new query data, that not needed by this query not queried by the views. But time of query execution is still to long. About 2 minutes

declare @.userID int

set @.userID = 104356

declare @.qp_0 int

set @.qp_0 = 0

DELETE ProcessAccounts WITH (ROWLOCK) WHERE spid=@.@.spid INSERT ProcessAccounts WITH (ROWLOCK) (account_id, spid) VALUES (@.userID, @.@.spid)

SELECT

[a0].[id],[a0].[Heading],[a0].[DocumentDate],[a0].[DocumentId],[a0].[Name],[a0].[PrimaryPhone],[a0].[PrimaryEmail],

[a1].[FIO],

[a3].[ContactTime],

[a4].[WorkPhone],[a4].[WorkEmail],[a4].[FIO],

[a5].[Value],

[a6].[Position],

[a7].[ContactTime]

FROM

(

SELECT [a0].[id],[a0].[Heading],[a0].[DocumentDate],[a0].[DocumentId],[a0].[Name],[a0].[PrimaryPhone],[a0].[PrimaryEmail], a0.Responsible_id, a0.ClientType_id, a0.ContactsInfo_id, a0.IsTemplate FROM [Bkc_EBM_Client] [a0]

INNER JOIN [ReadRights] [a0r] ON ([a0].[id] = [a0r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a0pa] ON ( [a0r].[account_id] = [a0pa].[account_id] )

) [a0]

LEFT JOIN [Bkc_EBM_ClientType] [a5] ON ( a0.ClientType_id = a5.[id] )

LEFT JOIN

(

SELECT [a1].[id], [a1].[FIO] FROM [Bkc_EBM_Person] [a1]

INNER JOIN [ReadRights] [a1r] ON ([a1].[id] = [a1r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a1pa] ON ( [a1r].[account_id] = [a1pa].[account_id] )

) [a1] ON ( a0.Responsible_id = a1.[id] )

LEFT JOIN [Bkc_EBM_ContactsInfo] [a2] ON ( a0.ContactsInfo_id = a2.[id] )

LEFT JOIN

(

SELECT [a3].[id], [a3].[ContactTime] FROM [Bkc_EBM_Contact] [a3]

INNER JOIN [ReadRights] [a3r] ON ([a3].[id] = [a3r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a3pa] ON ( [a3r].[account_id] = [a3pa].[account_id] )

) [a3] ON ( a2.LastContact_id = a3.[id] )

LEFT JOIN

(

SELECT [a4].[id], [a4].[WorkPhone],[a4].[WorkEmail],[a4].[FIO], [a4].[PrimaryEmployment_id] FROM [Bkc_EBM_Person] [a4]

INNER JOIN [ReadRights] [a4r] ON ([a4].[id] = [a4r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a4pa] ON ( [a4r].[account_id] = [a4pa].[account_id] )

) [a4] ON ( a2.LastContactPerson_id = a4.[id] )

LEFT JOIN

(

SELECT [a6].[id], [a6].[Position] FROM [Bkc_EBM_Employment] [a6]

INNER JOIN [ReadRights] [a6r] ON ([a6].[EmployedPerson_id] = [a6r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a6pa] ON ( [a6r].[account_id] = [a6pa].[account_id] )

) [a6] ON ( a4.PrimaryEmployment_id = a6.[id] )

LEFT JOIN

(

SELECT [a7].[id], [a7].[ContactTime] FROM [Bkc_EBM_Contact] [a7]

INNER JOIN [ReadRights] [a7r] ON ([a7].[id] = [a7r].[object_id] )

INNER JOIN ( SELECT [account_id] FROM [ProcessAccounts] WITH (NOLOCK) WHERE [spid] = @.@.SPID ) [a7pa] ON ( [a7r].[account_id] = [a7pa].[account_id] )

) [a7] ON ( a2.NextContact_id = a7.[id] )

WHERE ([a0].[IsTemplate] = @.qp_0 OR [a0].[IsTemplate] IS NULL )

DELETE ProcessAccounts WITH (ROWLOCK) WHERE spid=@.@.spid

Statistics

(1750 row(s) affected)

Table 'ReadRights'. Scan count 5891, logical reads 222578, physical reads 425, read-ahead reads 283, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'ProcessAccounts'. Scan count 6, logical reads 5891, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Contact'. Scan count 0, logical reads 7000, physical reads 98, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Employment'. Scan count 0, logical reads 33686288, physical reads 33, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Person'. Scan count 0, logical reads 7000, physical reads 60, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_ContactsInfo_View'. Scan count 0, logical reads 3500, physical reads 5, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_ClientType_View'. Scan count 0, logical reads 3500, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Table 'Bkc_EBM_Client'. Scan count 0, logical reads 33252, physical reads 43, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

SQL Server Execution Times:

CPU time = 111797 ms, elapsed time = 123889 ms.

Execution Plan

http://rsdn.ru/File/22090/plan4.rar

|||

Please post the scripts for all the tables involved and indexes.

To get performance you need to reduce the amount of data being read from Bkc_EBM_Employment

|||Do you have a where clause on your query ?|||

SimonS_ wrote:

Do you have a where clause on your query ?

Yes "WHERE ([a0].[IsTemplate] = @.qp_0 OR [a0].[IsTemplate] IS NULL ) " (see query in the answer above) but there is no records in database filtered by this condition.

About database

'ReadRights' ~ 500000 records
'ProcessAccounts' 1 record
'Bkc_EBM_Person' ~ 2500 records
'Bkc_EBM_Client' ~ 1700 records
'Bkc_EBM_ClientType' ~ 20 records
'Bkc_EBM_ContactsInfo' ~ 4000 records
'Bkc_EBM_Contact' ~ 5000 records
'Bkc_EBM_Employment' ~ 2500 records

Very strange, but it sims RECOMPILE option helps. Worktable is created even right after SQL Server restart. If RECOMPLIE not used after server restart Worktable not created.

|||

The problem is query plans. Your query won't change from one user to the next or from one template to the next however this means the same query plan will be used. However the same query plan will not be optimal for all situations.

What can happen is that a plan is put in the cache based on the first set of parameters supplied, if this plan is not suitable for all queries you can end up with the problem above.

The recompile will address this at the expense of having to compile the query every time.

|||

Thank you for your help Simon. RECOMPILE is really helps.

Maybe in my case using of parameters in a query is not the best choise? Especially @.userID ?

|||Can you still post the CREATE table statements and CREATE View statements so I can understand your query better, its quite difficult with your use of views to understand what is joining to what.|||

Script will be quite large. Maybe by email?

|||try SQLForumsATonarcDOTcom|||I send the script. Please check.|||Another problem. In SQL Server 2000 option (recompile) is not supported. Is there any way to enforce SQL Server 2000 to recompile execution plan every time?

Friday, March 9, 2012

how to download the image or file from the [Blobcontent] as file in sql server 2005?

hi,

i plan to use the database mail to send the mail. i created stored procedure to send the mail to all receipents ,.

Table fields like, profile,Toaddress,Bcc,Ccc,Blbcontents ,filename..subj,msgbody ,etc...,

download the blb & attach with the mail for the particular recepent

.

so., is it possible to download the blobcontent using Query? or any Other function available in Sqlserver 2005?

In order to attach files to an email in Database Mail on SQL Server 2005, the files must be on disk. If you are storing files at blobs (VarBinary or image) in your SQL Server database, you must extract them to disk before attaching them to your mail.

Does that answer your question?

Paul A. Mestemaker II

Program Manager

Microsoft SQL Server Manageability

http://blogs.msdn.com/sqlrem/

|||

thanks Mr.Paul A. Mestemaker,

my question is, Is any system procedure available to download the blob-content in sql server 2005 database itself?

Please let me know ..

any way, myself found the solution, please let me know the procedure is correct

i wrote the clr integrated procedure using c# application

the below steps i have done

1. created the ExportBlob.dll file

2. Created assembly with ExportBlob.dll.

3. Created Procedure to call the Dll file with param.

4. Created ownProcedure to send mail

5. if you want to send mail as Automatically, create new job & set the schedule time to run in sql server agents.

this code is working fine.

Create assembly

==============

USE [master]

Go

/* register the assembly in a SQL Server database using the CREATE ASSEMBLY statement */

CREATE ASSEMBLY ExportBlob

FROM 'D:\Extended_Proc\sp_exportBlob.dll'

WITH PERMISSION_SET = EXTERNAL_ACCESS

GO

GO

/****** Object: StoredProcedure [dbo].[xp_ExportBlob]

CREATE PROCEDURE [dbo].[xp_ExportBlob]

@.ServerName [nvarchar](25),

@.UID [nvarchar](50),

@.Pwd [nvarchar](25),

@.DBName [nvarchar](25),

@.Tbname [nvarchar](50),

@.FldName [nvarchar](100),

@.cndt [nvarchar](max),

@.Exportpath [nvarchar](100)

WITH EXECUTE AS CALLER

AS

EXTERNAL NAME [ExportBlob].[sp_exportBlob].[exportBlob] //

mail send

=========

SET @.DBName=db_name() /* Get & Assign the Current Database Name*/

SET @.Server=@.@.servername

Select @.ListOfAttachFiles='', @.Delimiter=';'

/*Create a Local Dir to save the File*/

set @.ExtractPath='C:\SQLdbmail_attched_files\

DECLARE CursorMailList CURSOR FOR

SELECT [MailID],

[Profile],

left(Subject,255),

[importance],

[MsgTo],

[CopyTo],

[BCCTo],

[Contents],

isnull(HasAttachment,0)

FROM MailTb Where Processed=0 Order by MailID

OPEN CursorMailList

FETCH NEXT FROM CursorMailList INTO @.MailID,@.Profile,@.m_subject,@.m_importance,@.m_Toaddress,@.m_ccaddress,@.m_Bccaddress,@.m_body,@.HasAttachment

WHILE (@.@.FETCH_STATUS = 0)

BEGIN

Select @.ListOfAttachFiles=@.ListOfAttachFiles + @.ExtractPath+Filename+@.Delimiter from Attachments where MailID=@.MailID

SET @.ListOfAttachFiles=left(@.ListOfAttachFiles,len(@.ListOfAttachFiles)-1)

SET @.cndtn='where Datalength(Blobcontents)>0 and MailID='+ convert(VARCHAR,@.MailID,25)

select @.FldNames='Blobcontents,Filename'

/*Download File in the server Dir */

/*passing param to dll , param=servername,UID,PWD,DatabaseName,Tablename,Feildname,wherecndtn,extractDir */

EXEC master..xp_ExportBlob @.Server, 'sa', 'pass', @.DBName, 'Attachments', @.FldNames, @.cndtn, @.ExtractPath

/*Get Missing Attchment Files */

BEGIN TRY

EXECUTE msdb..sp_send_dbmail

@.profile_name = @.Profile

,@.recipients = @.m_Toaddress

,@.copy_recipients = @.m_ccaddress

,@.blind_copy_recipients = @.m_Bccaddress

,@.body = @.m_body

,@.subject = @.m_subject

,@.importance = @.m_importance

,@.file_attachments = @.ListOfAttachFiles /* Eg. D:\mailDownload\filename.ext;c D:\mailDownload\filename2.ext */

,@.mailitem_id = @.mailitemid output

Update MailTb set Processed=1 where MailID=@.MailID /*Update back Mail sent scessfully*/

END TRY /*TRY*/

BEGIN CATCH

SET @.err=1

set @.ErrMsg = @.ErrMsg +'Failed to send Mail with Attachments. SDS MailID ='+convert(varchar,@.MailId,25)

END CATCH /*Catch*/

END /*

FETCH NEXT FROM CursorMailList INTO @.MailID,@.Profile,@.m_subject,@.m_importance,@.m_Toaddress,@.m_ccaddress,@.m_Bccaddress,@.m_body,@.HasAttachment

END /*WHILE*/

-- clean up; close & Deallocate the cursor

CLOSE CursorMailList

DEALLOCATE CursorMailList

c# application {Create library}

====================

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Data.SqlClient;

using System.Data.Sql;

using Microsoft.SqlServer.Server;

using System.Data.SqlTypes;

public class sp_exportBlob

{

// Identify that this is a SQL Stored Procedure

[SqlProcedure]

//summary

//FldNames should be BlobContents and Filename with Extension using comma Sepearator.

// [i.e., Fldnames="Blobcontents,Filename+Extension" ]

//

public static void exportBlob(string ServerName, string UID, string Pwd, string DBName, string TbName, string Fldnames, string Cndt, string ExtractPath)

{

SqlConnection sqlconn = new SqlConnection();

SqlDataReader sqlDr;

SqlCommand cmd;

FileStream fs;

BinaryWriter bw;

int Blobsize;

long blob, startIndex;

byte[] outBuffer;

string ExtractFileName = "";

try

{

int IndexBlobContents = 0;

sqlconn.ConnectionString = "Server=" + ServerName + ";UID=" + UID + ";Pwd=" + Pwd + ";Database=" + DBName;

sqlconn.Open();

Blobsize = 1024;// Initalize the BlobSize

cmd = new SqlCommand("SELECT " + Fldnames + " FROM " + TbName + " " + Cndt, sqlconn);

sqlDr = cmd.ExecuteReader();

while (sqlDr.Read())

{

ExtractFileName = ExtractPath + sqlDr[1].ToString();//dirname + filename

startIndex = 0; // Reset the starting byte for the new BLOB.

outBuffer = new byte[Blobsize];

if (File.Exists(@.ExtractFileName))

{

File.Delete(@.ExtractFileName);

}

fs = new FileStream(@.ExtractFileName, FileMode.OpenOrCreate, FileAccess.Write); // Create a file to hold the output.

bw = new BinaryWriter(fs);

blob = sqlDr.GetBytes(IndexBlobContents, startIndex, outBuffer, 0, Blobsize); // Read bytes into outByte[] and retain the number of bytes returned.

while (blob == Blobsize) // Continue while there are bytes beyond the size of the buffer.

{

bw.Write(outBuffer);

bw.Flush();

startIndex += Blobsize;

blob = sqlDr.GetBytes(IndexBlobContents, startIndex, outBuffer, 0, Blobsize);

}

bw.Write(outBuffer, 0, (int)blob);// Write the remaining buffer.

bw.Flush();

bw.Close();

fs.Close();

SqlContext.Pipe.Send("Downloaded successfully in " + ExtractFileName);

}

sqlDr.Close();

}

catch (Exception er)

{

SqlContext.Pipe.Send(er.Message);

}

finally

{

if (sqlconn.State == System.Data.ConnectionState.Open)

{

sqlconn.Close();

}

fs = null;

bw = null;

cmd = null;

sqlDr = null;

sqlconn = null;

}

}

}

|||

Looks pretty cool. I generally don't like to see dynamic SQL, but it seems like it's working for your architecture. Thanks for posting this so the community can benefit :-)

People ask about this quite a bit at conferences... now I have a place to direct them.

Paul A. Mestemaker II

Program Manager

Microsoft SQL Server Manageability

http://blogs.msdn.com/sqlrem/

|||

Hi Raj,

This solution is great. However, I am using a different environment :-

SQL 2005 and Java for this application.

So, i will not be able to use the c# piece of code.

c# application {Create library}

Thanks,

how to download the image or file from the [Blobcontent] as file in sql server 2005?

hi,

i plan to use the database mail to send the mail. i created stored procedure to send the mail to all receipents ,.

Table fields like, profile,Toaddress,Bcc,Ccc,Blbcontents ,filename..subj,msgbody ,etc...,

download the blb & attach with the mail for the particular recepent

.

so., is it possible to download the blobcontent using Query? or any Other function available in Sqlserver 2005?

In order to attach files to an email in Database Mail on SQL Server 2005, the files must be on disk. If you are storing files at blobs (VarBinary or image) in your SQL Server database, you must extract them to disk before attaching them to your mail.

Does that answer your question?

Paul A. Mestemaker II

Program Manager

Microsoft SQL Server Manageability

http://blogs.msdn.com/sqlrem/

|||

thanks Mr.Paul A. Mestemaker,

my question is, Is any system procedure available to download the blob-content in sql server 2005 database itself?

Please let me know ..

any way, myself found the solution, please let me know the procedure is correct

i wrote the clr integrated procedure using c# application

the below steps i have done

1. created the ExportBlob.dll file

2. Created assembly with ExportBlob.dll.

3. Created Procedure to call the Dll file with param.

4. Created ownProcedure to send mail

5. if you want to send mail as Automatically, create new job & set the schedule time to run in sql server agents.

this code is working fine.

Create assembly

==============

USE [master]

Go

/* register the assembly in a SQL Server database using the CREATE ASSEMBLY statement */

CREATE ASSEMBLY ExportBlob

FROM 'D:\Extended_Proc\sp_exportBlob.dll'

WITH PERMISSION_SET = EXTERNAL_ACCESS

GO

GO

/****** Object: StoredProcedure [dbo].[xp_ExportBlob]

CREATE PROCEDURE [dbo].[xp_ExportBlob]

@.ServerName [nvarchar](25),

@.UID [nvarchar](50),

@.Pwd [nvarchar](25),

@.DBName [nvarchar](25),

@.Tbname [nvarchar](50),

@.FldName [nvarchar](100),

@.cndt [nvarchar](max),

@.Exportpath [nvarchar](100)

WITH EXECUTE AS CALLER

AS

EXTERNAL NAME [ExportBlob].[sp_exportBlob].[exportBlob] //

mail send

=========

SET @.DBName=db_name() /* Get & Assign the Current Database Name*/

SET @.Server=@.@.servername

Select @.ListOfAttachFiles='', @.Delimiter=';'

/*Create a Local Dir to save the File*/

set @.ExtractPath='C:\SQLdbmail_attched_files\

DECLARE CursorMailList CURSOR FOR

SELECT [MailID],

[Profile],

left(Subject,255),

[importance],

[MsgTo],

[CopyTo],

[BCCTo],

[Contents],

isnull(HasAttachment,0)

FROM MailTb Where Processed=0 Order by MailID

OPEN CursorMailList

FETCH NEXT FROM CursorMailList INTO @.MailID,@.Profile,@.m_subject,@.m_importance,@.m_Toaddress,@.m_ccaddress,@.m_Bccaddress,@.m_body,@.HasAttachment

WHILE (@.@.FETCH_STATUS = 0)

BEGIN

Select @.ListOfAttachFiles=@.ListOfAttachFiles + @.ExtractPath+Filename+@.Delimiter from Attachments where MailID=@.MailID

SET @.ListOfAttachFiles=left(@.ListOfAttachFiles,len(@.ListOfAttachFiles)-1)

SET @.cndtn='where Datalength(Blobcontents)>0 and MailID='+ convert(VARCHAR,@.MailID,25)

select @.FldNames='Blobcontents,Filename'

/*Download File in the server Dir */

/*passing param to dll , param=servername,UID,PWD,DatabaseName,Tablename,Feildname,wherecndtn,extractDir */

EXEC master..xp_ExportBlob @.Server, 'sa', 'pass', @.DBName, 'Attachments', @.FldNames, @.cndtn, @.ExtractPath

/*Get Missing Attchment Files */

BEGIN TRY

EXECUTE msdb..sp_send_dbmail

@.profile_name = @.Profile

,@.recipients = @.m_Toaddress

,@.copy_recipients = @.m_ccaddress

,@.blind_copy_recipients = @.m_Bccaddress

,@.body = @.m_body

,@.subject = @.m_subject

,@.importance = @.m_importance

,@.file_attachments = @.ListOfAttachFiles /* Eg. D:\mailDownload\filename.ext;c D:\mailDownload\filename2.ext */

,@.mailitem_id = @.mailitemid output

Update MailTb set Processed=1 where MailID=@.MailID /*Update back Mail sent scessfully*/

END TRY /*TRY*/

BEGIN CATCH

SET @.err=1

set @.ErrMsg = @.ErrMsg +'Failed to send Mail with Attachments. SDS MailID ='+convert(varchar,@.MailId,25)

END CATCH /*Catch*/

END /*

FETCH NEXT FROM CursorMailList INTO @.MailID,@.Profile,@.m_subject,@.m_importance,@.m_Toaddress,@.m_ccaddress,@.m_Bccaddress,@.m_body,@.HasAttachment

END /*WHILE*/

-- clean up; close & Deallocate the cursor

CLOSE CursorMailList

DEALLOCATE CursorMailList

c# application {Create library}

====================

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Data.SqlClient;

using System.Data.Sql;

using Microsoft.SqlServer.Server;

using System.Data.SqlTypes;

public class sp_exportBlob

{

// Identify that this is a SQL Stored Procedure

[SqlProcedure]

//summary

//FldNames should be BlobContents and Filename with Extension using comma Sepearator.

// [i.e., Fldnames="Blobcontents,Filename+Extension" ]

//

public static void exportBlob(string ServerName, string UID, string Pwd, string DBName, string TbName, string Fldnames, string Cndt, string ExtractPath)

{

SqlConnection sqlconn = new SqlConnection();

SqlDataReader sqlDr;

SqlCommand cmd;

FileStream fs;

BinaryWriter bw;

int Blobsize;

long blob, startIndex;

byte[] outBuffer;

string ExtractFileName = "";

try

{

int IndexBlobContents = 0;

sqlconn.ConnectionString = "Server=" + ServerName + ";UID=" + UID + ";Pwd=" + Pwd + ";Database=" + DBName;

sqlconn.Open();

Blobsize = 1024;// Initalize the BlobSize

cmd = new SqlCommand("SELECT " + Fldnames + " FROM " + TbName + " " + Cndt, sqlconn);

sqlDr = cmd.ExecuteReader();

while (sqlDr.Read())

{

ExtractFileName = ExtractPath + sqlDr[1].ToString();//dirname + filename

startIndex = 0; // Reset the starting byte for the new BLOB.

outBuffer = new byte[Blobsize];

if (File.Exists(@.ExtractFileName))

{

File.Delete(@.ExtractFileName);

}

fs = new FileStream(@.ExtractFileName, FileMode.OpenOrCreate, FileAccess.Write); // Create a file to hold the output.

bw = new BinaryWriter(fs);

blob = sqlDr.GetBytes(IndexBlobContents, startIndex, outBuffer, 0, Blobsize); // Read bytes into outByte[] and retain the number of bytes returned.

while (blob == Blobsize) // Continue while there are bytes beyond the size of the buffer.

{

bw.Write(outBuffer);

bw.Flush();

startIndex += Blobsize;

blob = sqlDr.GetBytes(IndexBlobContents, startIndex, outBuffer, 0, Blobsize);

}

bw.Write(outBuffer, 0, (int)blob);// Write the remaining buffer.

bw.Flush();

bw.Close();

fs.Close();

SqlContext.Pipe.Send("Downloaded successfully in " + ExtractFileName);

}

sqlDr.Close();

}

catch (Exception er)

{

SqlContext.Pipe.Send(er.Message);

}

finally

{

if (sqlconn.State == System.Data.ConnectionState.Open)

{

sqlconn.Close();

}

fs = null;

bw = null;

cmd = null;

sqlDr = null;

sqlconn = null;

}

}

}

|||

Looks pretty cool. I generally don't like to see dynamic SQL, but it seems like it's working for your architecture. Thanks for posting this so the community can benefit :-)

People ask about this quite a bit at conferences... now I have a place to direct them.

Paul A. Mestemaker II

Program Manager

Microsoft SQL Server Manageability

http://blogs.msdn.com/sqlrem/

|||

Hi Raj,

This solution is great. However, I am using a different environment :-

SQL 2005 and Java for this application.

So, i will not be able to use the c# piece of code.

c# application {Create library}

Thanks,

how to download the image or file from the [Blobcontent] as file in sql server 2005?

hi,

i plan to use the database mail to send the mail. i created stored procedure to send the mail to all receipents ,.

Table fields like, profile,Toaddress,Bcc,Ccc,Blbcontents ,filename..subj,msgbody ,etc...,

download the blb & attach with the mail for the particular recepent

.

so., is it possible to download the blobcontent using Query? or any Other function available in Sqlserver 2005?

In order to attach files to an email in Database Mail on SQL Server 2005, the files must be on disk. If you are storing files at blobs (VarBinary or image) in your SQL Server database, you must extract them to disk before attaching them to your mail.

Does that answer your question?

Paul A. Mestemaker II

Program Manager

Microsoft SQL Server Manageability

http://blogs.msdn.com/sqlrem/

|||

thanks Mr.Paul A. Mestemaker,

my question is, Is any system procedure available to download the blob-content in sql server 2005 database itself?

Please let me know ..

any way, myself found the solution, please let me know the procedure is correct

i wrote the clr integrated procedure using c# application

the below steps i have done

1. created the ExportBlob.dll file

2. Created assembly with ExportBlob.dll.

3. Created Procedure to call the Dll file with param.

4. Created ownProcedure to send mail

5. if you want to send mail as Automatically, create new job & set the schedule time to run in sql server agents.

this code is working fine.

Create assembly

==============

USE [master]

Go

/* register the assembly in a SQL Server database using the CREATE ASSEMBLY statement */

CREATE ASSEMBLY ExportBlob

FROM 'D:\Extended_Proc\sp_exportBlob.dll'

WITH PERMISSION_SET = EXTERNAL_ACCESS

GO

GO

/****** Object: StoredProcedure [dbo].[xp_ExportBlob]

CREATE PROCEDURE [dbo].[xp_ExportBlob]

@.ServerName [nvarchar](25),

@.UID [nvarchar](50),

@.Pwd [nvarchar](25),

@.DBName [nvarchar](25),

@.Tbname [nvarchar](50),

@.FldName [nvarchar](100),

@.cndt [nvarchar](max),

@.Exportpath [nvarchar](100)

WITH EXECUTE AS CALLER

AS

EXTERNAL NAME [ExportBlob].[sp_exportBlob].[exportBlob] //

mail send

=========

SET @.DBName=db_name() /* Get & Assign the Current Database Name*/

SET @.Server=@.@.servername

Select @.ListOfAttachFiles='', @.Delimiter=';'

/*Create a Local Dir to save the File*/

set @.ExtractPath='C:\SQLdbmail_attched_files\

DECLARE CursorMailList CURSOR FOR

SELECT [MailID],

[Profile],

left(Subject,255),

[importance],

[MsgTo],

[CopyTo],

[BCCTo],

[Contents],

isnull(HasAttachment,0)

FROM MailTb Where Processed=0 Order by MailID

OPEN CursorMailList

FETCH NEXT FROM CursorMailList INTO @.MailID,@.Profile,@.m_subject,@.m_importance,@.m_Toaddress,@.m_ccaddress,@.m_Bccaddress,@.m_body,@.HasAttachment

WHILE (@.@.FETCH_STATUS = 0)

BEGIN

Select @.ListOfAttachFiles=@.ListOfAttachFiles + @.ExtractPath+Filename+@.Delimiter from Attachments where MailID=@.MailID

SET @.ListOfAttachFiles=left(@.ListOfAttachFiles,len(@.ListOfAttachFiles)-1)

SET @.cndtn='where Datalength(Blobcontents)>0 and MailID='+ convert(VARCHAR,@.MailID,25)

select @.FldNames='Blobcontents,Filename'

/*Download File in the server Dir */

/*passing param to dll , param=servername,UID,PWD,DatabaseName,Tablename,Feildname,wherecndtn,extractDir */

EXEC master..xp_ExportBlob @.Server, 'sa', 'pass', @.DBName, 'Attachments', @.FldNames, @.cndtn, @.ExtractPath

/*Get Missing Attchment Files */

BEGIN TRY

EXECUTE msdb..sp_send_dbmail

@.profile_name = @.Profile

,@.recipients = @.m_Toaddress

,@.copy_recipients = @.m_ccaddress

,@.blind_copy_recipients = @.m_Bccaddress

,@.body = @.m_body

,@.subject = @.m_subject

,@.importance = @.m_importance

,@.file_attachments = @.ListOfAttachFiles /* Eg. D:\mailDownload\filename.ext;c D:\mailDownload\filename2.ext */

,@.mailitem_id = @.mailitemid output

Update MailTb set Processed=1 where MailID=@.MailID /*Update back Mail sent scessfully*/

END TRY /*TRY*/

BEGIN CATCH

SET @.err=1

set @.ErrMsg = @.ErrMsg +'Failed to send Mail with Attachments. SDS MailID ='+convert(varchar,@.MailId,25)

END CATCH /*Catch*/

END /*

FETCH NEXT FROM CursorMailList INTO @.MailID,@.Profile,@.m_subject,@.m_importance,@.m_Toaddress,@.m_ccaddress,@.m_Bccaddress,@.m_body,@.HasAttachment

END /*WHILE*/

-- clean up; close & Deallocate the cursor

CLOSE CursorMailList

DEALLOCATE CursorMailList

c# application {Create library}

====================

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Data.SqlClient;

using System.Data.Sql;

using Microsoft.SqlServer.Server;

using System.Data.SqlTypes;

public class sp_exportBlob

{

// Identify that this is a SQL Stored Procedure

[SqlProcedure]

//summary

//FldNames should be BlobContents and Filename with Extension using comma Sepearator.

// [i.e., Fldnames="Blobcontents,Filename+Extension" ]

//

public static void exportBlob(string ServerName, string UID, string Pwd, string DBName, string TbName, string Fldnames, string Cndt, string ExtractPath)

{

SqlConnection sqlconn = new SqlConnection();

SqlDataReader sqlDr;

SqlCommand cmd;

FileStream fs;

BinaryWriter bw;

int Blobsize;

long blob, startIndex;

byte[] outBuffer;

string ExtractFileName = "";

try

{

int IndexBlobContents = 0;

sqlconn.ConnectionString = "Server=" + ServerName + ";UID=" + UID + ";Pwd=" + Pwd + ";Database=" + DBName;

sqlconn.Open();

Blobsize = 1024;// Initalize the BlobSize

cmd = new SqlCommand("SELECT " + Fldnames + " FROM " + TbName + " " + Cndt, sqlconn);

sqlDr = cmd.ExecuteReader();

while (sqlDr.Read())

{

ExtractFileName = ExtractPath + sqlDr[1].ToString();//dirname + filename

startIndex = 0; // Reset the starting byte for the new BLOB.

outBuffer = new byte[Blobsize];

if (File.Exists(@.ExtractFileName))

{

File.Delete(@.ExtractFileName);

}

fs = new FileStream(@.ExtractFileName, FileMode.OpenOrCreate, FileAccess.Write); // Create a file to hold the output.

bw = new BinaryWriter(fs);

blob = sqlDr.GetBytes(IndexBlobContents, startIndex, outBuffer, 0, Blobsize); // Read bytes into outByte[] and retain the number of bytes returned.

while (blob == Blobsize) // Continue while there are bytes beyond the size of the buffer.

{

bw.Write(outBuffer);

bw.Flush();

startIndex += Blobsize;

blob = sqlDr.GetBytes(IndexBlobContents, startIndex, outBuffer, 0, Blobsize);

}

bw.Write(outBuffer, 0, (int)blob);// Write the remaining buffer.

bw.Flush();

bw.Close();

fs.Close();

SqlContext.Pipe.Send("Downloaded successfully in " + ExtractFileName);

}

sqlDr.Close();

}

catch (Exception er)

{

SqlContext.Pipe.Send(er.Message);

}

finally

{

if (sqlconn.State == System.Data.ConnectionState.Open)

{

sqlconn.Close();

}

fs = null;

bw = null;

cmd = null;

sqlDr = null;

sqlconn = null;

}

}

}

|||

Looks pretty cool. I generally don't like to see dynamic SQL, but it seems like it's working for your architecture. Thanks for posting this so the community can benefit :-)

People ask about this quite a bit at conferences... now I have a place to direct them.

Paul A. Mestemaker II

Program Manager

Microsoft SQL Server Manageability

http://blogs.msdn.com/sqlrem/

|||

Hi Raj,

This solution is great. However, I am using a different environment :-

SQL 2005 and Java for this application.

So, i will not be able to use the c# piece of code.

c# application {Create library}

Thanks,