VB.NET upload SQL script to create database and tables - sql

I have written a small application. On first run of the application I want to upload an SQL script to the local SQL Server Express Instance.
On my development machine I have created the database and tables and have exported the scripts using SSMS to a sql file. I can import that file into SSMS and execute it, and the database will be created. I do not know how to perform the same process using VB.NET
I added the sql file to my project as a resource and I have included the first few lines below
USE [master]
GO
/****** Object: Database [MyProject] Script Date: 5/04/2016 11:30:42 PM ******/
CREATE DATABASE [MyProject]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'MyProject', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\MyProject.mdf' , SIZE = 4160KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'MyProject_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\MyProject_log.ldf' , SIZE = 1040KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [MyProject] SET COMPATIBILITY_LEVEL = 110
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [MyProject].[dbo].[sp_fulltext_database] #action = 'enable'
end
GO
ALTER DATABASE [MyProject] SET ANSI_NULL_DEFAULT OFF
...
...
USE [MyProject]
GO
/****** Object: Table [dbo].[SomeTable] Script Date: 5/04/2016 11:30:42 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SomeTable](
[Identifier] [int] IDENTITY(1,1) NOT NULL,
....
I then used the below code to upload the SQL to the database
Private Sub Create_SQL_Database()
Dim connetionString As String = "Data Source=localhost\SQLEXPRESS;Trusted_Connection=YES"
Dim cnn As SqlConnection = New SqlConnection(connetionString)
Dim cmd As SqlCommand = New SqlCommand()
Try
cnn.Open()
Console.Writeline("Connection Open ! Attempting to create database")
cmd.CommandText = My.Resources.CreateDatabaseSQL
cmd.Connection = cnn
Try
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Error - " & ex.Message)
End Try
This did not work and I received a lot of errors in a messagebox - Incorrect syntax near 'GO' followed by Database 'MyProject' does not exist. Make sure that the name is entered correctly.
I tried removing all of the lines containing GO but was still left with the error - Database 'MyProject' does not exist. Make sure that the name is entered correctly.
I am no expert on this matter but It would seem to me that the GO commands will commit the changes to the database. Because I have been removed the lines with GO on them when the script reaches this line
USE [MyProject]
the database does not exist because the previous steps have not been committed.
What do I need to do in VB.NET to be able to upload this file to the database and create my database and tables?
Thanks.

Related

How to insert data into a table where a stored procedure is triggered to export a file to the folder of DB Server side

I want to export data as a file from the table with the stored procedure which was to be triggered when the table was inserted with any data by the SQL of inserting data.
It has worked when I executed some SQL for inserting data with the query tool of the pgAdmin console. I could see the file exported from the table.
I made VBA code to insert data to that table with ADO.
It worked without the stored procedure to export a file from that table when some data was inserted to that table.
My intention is:
Using VBA, insert data into that table
The stored procedure triggered to export data as a file from that table
From the console like the pgAdmin query tool, it works.
From the VBA of the Excel file, it wouldn't work with the message that it can create a file for the server.
Without the stored procedure, the VBA inserts data into the table work.
The problem is I need a file.
I guessed the problem is the lack of authority to create a file in a folder of the server.
It didn't work the first time when the console executed the insert query before I gave permission to create a file.
If it were the same reason, I have to know how to give permission to the VBA code or the Excel Application. Am I right?
From the pgadmin4 console, it works fine.
But from the vba, it doesn’t work
[Intention] If tb_img table were inserted with a binary image file, the image file will be exported to the target folder.
— Function I created
Create or Replace function bytea_export()
returns trigger
language ‘plpgsql’
as $$
declare
l_oid oid;
r record;
begin
l_oid := lo_from_bytea(0, New.f_img);
perform lo_export(l_oid, ‘D:\IMG\’ || New.f_nm);
perfor lo_unlink(l_oid);
return new;
end;
$$;
Alter function bytea_export()
owner to postgres;
grant execute on function bytea_export to postgres;
— Trigger I created
Create Trigger trg_img
after insert or update on tb_img
for each row
execute procedure bytea_export();
— Table I created
Create table tb_img(
f_nm text
, f_img bytea
, f_dwn varchar(1)
);
— VBA I created
It works fine without the trigger above.
With the trigger, It doesn’t work (message is “The file couldn’t be created to the folder.”)
Sub Insert_image()
dim x_path, x_file, binaryData
x_path = thisworkbook.path & “\IMG”
x_file = “Test.png”
binaryData = readbinaryfile(x_path & “\” & x_file)
call insertfiletoDB(binaryData, x_file)
End sub
function readbinaryfile(filename)
const adTypebinary = 1
dim BinaryStream
set BinaryStream = CreateObject(“ADODB.Stream”)
BinaryStream.Type = adTypeBinary
BinaryStream.Open
BinaryStream.LoadFromFile filename
ReadBinaryFile = BinaryStream.Read
End function
Function insertfiletoDB(binarydata, f_nm)
dim sql, connstr, conndb as ADODB.Connection
dim rs as ADODB.Recordset
sql = “insert into tb_img valeus (‘“
sql = sql & f_nm & “‘, bytea_import(‘“ & f_nm & “‘))”
connstr = “DSN=PostgresSQL;Uid=postgres, Pwd= xxxxxxx ;
set conndb = new adodb.connection
conndb.open connstr
set rs = conndb.execute(sql)
conndb.close
set conndb = nothing
end function

SQL query to backup a database returns error when executed as a SqlCommand from code

The following SQL query was modified from this SO post and it runs properly in SSMS. My objective is to keep an updated database copy that serves as a backup and is readily available in the server to be accessed from code.
USE master;
ALTER DATABASE [conf.HelpDbBu] SET OFFLINE WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [conf.HelpDbBu] SET ONLINE;
DROP DATABASE [conf.HelpDbBu]
USE [conf.HelpDb];
BACKUP DATABASE [conf.HelpDb]
TO DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'
WITH FORMAT,
MEDIANAME = 'SQLServerBackups',
NAME = 'Full Backup of conf.HelpDb';
USE master
RESTORE VERIFYONLY
FROM DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
RESTORE FILELISTONLY
FROM DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
RESTORE DATABASE [conf.HelpDbBu]
FROM DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'
WITH RECOVERY,
MOVE 'conf.HelpDb' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb.mdf',
MOVE 'conf.HelpDb_log' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb_log.ldf';
ALTER AUTHORIZATION ON DATABASE::[conf.HelpDbBu] TO SA;
GO
Not being certain of the best way to execute this query from code, I settled on running an SQL command using a SqlConnection. The following code works: (certain parts are currently hard coded that will be changed after the bugs are ironed out)
Public Shared Function ExecuteSQLCommand()
Dim commandText = "USE master;" &
"ALTER DATABASE [conf.HelpDbBu] SET OFFLINE WITH ROLLBACK IMMEDIATE;" &
"ALTER DATABASE [conf.HelpDbBu] SET ONLINE;" &
"DROP DATABASE [conf.HelpDbBu]" &
"USE [conf.HelpDb];" &
"BACKUP DATABASE [conf.HelpDb]" &
"TO DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'" &
"With Format," &
"MEDIANAME = 'SQLServerBackups'," &
"NAME = 'Full Backup of conf.HelpDb';" &
"RESTORE DATABASE [conf.HelpDbBu]" &
"From DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak'" &
"With RECOVERY," &
"MOVE 'conf.HelpDb' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb.mdf', " &
"MOVE 'conf.HelpDb_log' TO 'C:\tfsCollateral\_projects\conf\dbBackups\conf.HelpDb_log.ldf';" &
"ALTER AUTHORIZATION ON DATABASE:: [conf.HelpDbBu] TO SA;"
Using connection As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("HelpDbConnection").ConnectionString)
Dim command As SqlCommand = New SqlCommand(commandText, connection)
command.Connection.Open()
command.ExecuteNonQuery()
End Using
Return 1
End Function
The connection string is:
connectionString="Data Source=<my pcname>\SQLEXPRESS; Initial Catalog=conf.HelpDb;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
But the original query included the following lines:
USE master
RESTORE VERIFYONLY
From DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
RESTORE FILELISTONLY
From DISK = 'C:\tfsCollateral\_projects\conf\dbBackups\conf_HelpDb.Bak';
The lines above errored out with the following message:
System.Data.SqlClient.SqlException: 'Database 'masterRESTORE' does not exist. Make sure that the name is entered correctly.'
I added a colon to the first line above making it USE master;. But now I have the following error and I am unable to see the problem.
System.Data.SqlClient.SqlException: 'Incorrect syntax near 'DISK'.'
The purpose of the RESTORE FILELISTONLY wasn't perfectly clear to me, but I presumed it was to find out the exact filenames in the .Bak file to be restored so the subsequent RESTORE DATABASE command could be properly populated.
While the vb.net code shown above runs without the 5 lines of SQL code that created the errors, I am unable to execute the backup verification. I'm not sure if the RESTORE FILELISTONLY is really necessary in this case.
So my question is: How do I fix things so the verification can be performed?

Running a SQL Server stored proecdure with OPENROWSET in VB.Net

I am trying to automatically import tables from an excel sheet into a table in an SQL database via VB.net. So far I have done the following:
I created a stored procedure in the database which imports the table via openrowset:
CREATE PROCEDURE ImportTable
AS
SET NOCOUNT ON;
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
SELECT *
INTO [Table]
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=C:\ExcelFile.xlsm', Table$);
GO
Once created this procedure works perfectly when executed in SSMS.
I then wrote a script in VB.net to run the stored procedure with the same login details:
Dim ConnectionString As String
Dim sqlCon As SqlConnection
' Open a database connection and use it to run the stored procedure
ConnectionString = "Data Source=ServerName;" &
"Initial Catalog=DBName;" &
"User=UserName;" &
"Password=Password;" &
"Integrated Security=SSPI;"
sqlCon = New SqlConnection(ConnectionString)
Using (sqlCon)
Dim sqlComm As New SqlCommand
sqlComm.Connection = sqlCon
sqlComm.CommandText = "ImportTable"
sqlComm.CommandType = CommandType.StoredProcedure
sqlCon.Open()
sqlComm.ExecuteNonQuery()
End Using
However when I try to run the SP in VB.net (or VB excel) I get the following error:
System.Data.SqlClient.SqlException: 'Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "Unspecified error".'
I have looked around and found multiple threads on getting this to work in SSMS, but no solutions for a situation where it runs fine in SSMS but not in VB.net.
Any idea why the SP wont run through a method external to SSMS?
Craig
First Make sure the Excel file isn't open.
Then you need to check whether you have installed the 2007 Office System Driver: Data Connectivity Components which is necessary for Microsoft OLEDB ACE 12.0 driver to work.
or you can
USE [master]
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
GO
Nice Link

SQL Server Table Fails to Update

This is just driving me crazy. I have a small SQL Server 2012 table with the following columns:
id int (this is an IDENTITY column)
DateNewsletter smalldatetime
SubjectNewsletter varchar(100)
ContentHeader varchar(MAX)
ContentNewsletter varchar(MAX)
ContentFooter varchar(MAX)
NewsletterSent bit
DateSent smalldatetime
ApprovalPending bit
PriorityHigh bit
There are 583 rows in the table.
Here's the problem:
I can SELECT * with no problem
I can INSERT INTO with no problem
However, when I run the following query, everything blows up:
UPDATE tblElinesNewsletter
SET NewsletterSent = 1,
DateSent = GETDATE(),
ApprovalPending = 0
WHERE (NewsletterSent = 0)
Whenever I run the above code, I get a timeout error. The timeout error is the same if I run it from ASP.NET page or from SQL Server Management Studio.
Also, if I right-click from SSMS and choose 'Edit Top 200 Rows...', it will display the grid and let me edit. But as soon as I click away and it's performing the update, it's blowing up.
I've tried the following already:
Rebuild the index
Create a brand new table with same schema and transfer data over there
Restart the server
Go to home depot and purchase large can of spackle to fix holes in office wall (from banging my head against)
This is not a large table. It simply stores HTML for an email newsletter.
It didn't always do this, and only started about a few months ago. It worked fine before that.
Now, all of the above said, here's the kicker: it doesn't do this all the time. Sometimes it works. What noticed is that if there's a longer newsletter in the table, it seems to not work vs. if the newsletter is very short. These are simple newsletters and not too fancy, here's one right here: http://unitedafa.org/news/elines/view/?id=104169
This is pulling from the database/table that I discuss above.
This SQL Server installation is on a Windows Server 2012 box with 6 GB RAM and only runs a few websites that don't get that much traffic.
One thing I'm noticing as I'm trying to debug this, is that when I execute the SQL Server stored procedure from the ASP.NET web page, when it fails, this seems to freeze up the SQL Server and I can't run the same stored procedure in SSMS. However, once I restart the server, I can then open SSMS and execute the stored procedure. Again, though if I execute the stored procedure from the web page, it 'freezes' up the server again and I can't run any update query against that table.
Just for reference, here's the actual stored procedure that's being called from the page:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ======================================================
-- Author: Christopher Lee
-- Create date: 16-Aug-2012
-- Modify date: 16-Aug-2012
-- Description: Mark all records as Sent.
-- ======================================================
ALTER PROCEDURE [dbo].[sProc_Elines_Send_MarkComplete]
AS
BEGIN TRANSACTION
UPDATE tblElinesNewsletter
SET NewsletterSent = 1,
DateSent = GETDATE(),
ApprovalPending = 0
WHERE (NewsletterSent = 0)
COMMIT
Also, here's the CREATE TABLE script:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tblElinesNewsletter]
(
[id] [int] IDENTITY(100543,1) NOT NULL,
[DateNewsletter] [smalldatetime] NOT NULL,
[SubjectNewsletter] [varchar](100) NOT NULL,
[ContentHeader] [varchar](max) NOT NULL,
[ContentNewsletter] [varchar](max) NOT NULL,
[ContentFooter] [varchar](max) NOT NULL,
[NewsletterSent] [bit] NOT NULL,
[DateSent] [smalldatetime] NULL,
[ApprovalPending] [bit] NOT NULL,
[PriorityHigh] [bit] NOT NULL,
CONSTRAINT [PK_tblElinesNewsletter2]
PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[tblElinesNewsletter]
ADD CONSTRAINT [DF_tblElinesNewsletter2_PriorityHigh] DEFAULT ((0)) FOR [PriorityHigh]
GO
Any idea what on earth I'm doing wrong? BTW, I'm not a DBA and more familiar with ASP.NET web code, etc., more than SQL statements.
Any help or advice would be appreciated!
-- Chris
PS, here's some additional info:
SQL Server Query Execution Plan on the Stored Proc:
[SQL Server Execution Plan Screenshot][1]
Here's some additional info:
There's enough hard drive space.
There's no other concurrent processes.
The stored proc is actually executed in a sequence with two other before it. Here's the code from the executing page:
Protected Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
Call WriteNewsletterFile()
Call SendNewsletter()
Call UpdateRecord()
End Sub
So the WriteNewsletterFile() and the SendNewsletter() subroutines work fine. It blows up on the UpdateRecord subroutine. Here's the code for each of the routines:
Sub WriteNewsletterFile()
Dim NewsID As String = ""
Dim Conn As SqlConnection
Dim Cmd As SqlCommand
Dim Rdr As SqlDataReader
Conn = New SqlConnection(ConfigurationManager.ConnectionStrings("UnitedAFAConnectionStringNSS").ConnectionString)
Cmd = New SqlCommand()
Cmd.CommandText = "sProc_Elines_Send_GetContentPending"
Cmd.CommandType = CommandType.StoredProcedure
Cmd.Connection = Conn
Cmd.Connection.Open()
Rdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection)
If Rdr.HasRows Then
While Rdr.Read
NewsID = Rdr("id")
NewsletterSubject = Rdr("SubjectNewsletter")
NewsletterHeader = Rdr("ContentHeader")
NewsletterContent = Rdr("ContentNewsletter")
NewsletterFooter = Rdr("ContentFooter")
End While
End If
Conn.Close()
Conn.Dispose()
Cmd.Dispose()
' Header
NewsletterHeaderForEmail = NewsletterHeader.Replace("<p>", "<p style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt; line-height: 1.3em;margin-bottom:1em"">")
NewsletterHeaderForEmail = NewsletterHeaderForEmail.Replace("<li>", "<li style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt; line-height: 1.3em;margin-bottom:1em"">")
NewsletterHeaderForEmail = NewsletterHeaderForEmail.Replace("[NewsID]", NewsID)
' Footer
NewsletterFooterForEmail = NewsletterFooter.Replace("<p>", "<p style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt; line-height: 1.3em;margin-bottom:1em"">")
NewsletterFooterForEmail = NewsletterFooterForEmail.Replace("<li>", "<li style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt; line-height: 1.3em;margin-bottom:1em"">")
' Content
NewsletterContentForEmail = NewsletterContent.Replace("<p>", "<p style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt; line-height: 1.3em;margin-bottom:1em"">")
NewsletterContentForEmail = NewsletterContentForEmail.Replace("<li>", "<li style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt; line-height: 1.3em;margin-bottom:1em"">")
NewsletterContentForEmail = "<table border=""0"" cellpadding=""0"" cellspacing=""0""><tr><td style=""font-family: Arial, Helvetica, sans-serif; font-size: 12pt"">" & NewsletterContentForEmail & "</td></tr></table>"
NewsletterFinalReadyForSending = NewsletterHeaderForEmail & NewsletterContentForEmail & NewsletterFooterForEmail
Dim filePath2 As String = "C:\Programs\SendElines.bat"
Dim w2 As StreamWriter
w2 = File.CreateText(filePath2)
w2.WriteLine("START """" ""C:\Program Files (x86)\Gammadyne Mailer\gm.exe"" /s /n /subject""" & NewsletterSubject & """ /html""C:\Programs\elines.html"" ""C:\Users\Public\Documents\Newsletters\Elines\Sending Template - Elines.mmp""")
w2.Flush()
w2.Close()
Dim filePath As String = "C:\Programs\elines.html"
Dim w As StreamWriter
w = File.CreateText(filePath)
w.WriteLine(NewsletterFinalReadyForSending)
w.Flush()
w.Close()
End Sub
Sub SendNewsletter()
Dim Conn As New SqlConnection(ConfigurationManager.ConnectionStrings("UnitedAFAConnectionStringAfaNewsletters").ConnectionString)
Dim MySQL As String = "sProc_SendElines"
Dim Cmd As New Data.SqlClient.SqlCommand(MySQL, Conn)
Cmd.CommandType = CommandType.StoredProcedure
Conn.Open()
Cmd.ExecuteNonQuery()
Conn.Close()
Conn.Dispose()
End Sub
Sub UpdateRecord()
Dim Conn As New SqlConnection(ConfigurationManager.ConnectionStrings("UnitedAFAConnectionStringNSS").ConnectionString)
Dim MySQL As String = "sProc_Elines_Send_MarkComplete"
Dim Cmd As New Data.SqlClient.SqlCommand(MySQL, Conn)
Cmd.CommandType = CommandType.StoredProcedure
Conn.Open()
Cmd.ExecuteNonQuery()
Conn.Close()
Conn.Dispose()
End Sub
And here's the code for the SendElines Subroutine:
USE [afanewsletters]
GO
/****** Object: StoredProcedure [dbo].[sProc_SendElines] Script Date: 9/5/2017 2:51:08 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ======================================================
-- Author: Christopher Lee
-- Create date: 21-Aug-2012
-- Modify date: 21-Aug-2012
-- Description: Runs the Elines sending BAT file.
-- ======================================================
ALTER PROCEDURE [dbo].[sProc_SendElines]
AS
EXEC xp_logevent 67845, 'Send Elines', informational
I should point out that the SendElines() stored proc is on a different database (but on same server). Again though, to be clear, the first two subroutines work fine. It's just the sProc_Elines_Send_MarkComplete that blows up.
Here's the code for sProc_Elines_Send_GetContentPending:
USE [Newsletters]
GO
/****** Object: StoredProcedure [dbo].[sProc_Elines_Send_GetContentPending] Script Date: 9/6/2017 6:57:06 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ======================================================
-- Author: Christopher Lee
-- Create date: 16-Aug-2012
-- Modify date: 16-Aug-2012
-- Description: Get content for Elines for approval.
-- ======================================================
ALTER PROCEDURE [dbo].[sProc_Elines_Send_GetContentPending]
AS
BEGIN TRY
BEGIN TRANSACTION
SELECT * FROM tblElinesNewsletter
WHERE (NewsletterSent = 0)
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK
RAISERROR ('Problem with sProc_Elines_Send_GetContentPending, please contact the MEC Webmaster at webmaster#unitedafa.org.', 16, 1)
END CATCH
Here's the results of the DBCC OPENTRAN I ran. The first two stored procs (sProc_Elines_Send_GetContentPending and sProc_SendElines) executed successfully. However, when sProc_Elines_Send_MarkComplete ran and hung, I ran the DBCC OPENTRAN which contained the message: "No active open transactions." Screenshot enclosed: Here's the DBCC OPENTRAN screenshot
In this code
Rdr = Cmd.ExecuteReader(CommandBehavior.CloseConnection)
If Rdr.HasRows Then
While Rdr.Read
....
End While
End If
Conn.Close()
Conn.Dispose()
you do not close and dispose the reader. I don't know the internals of SqlConnection and SqlDataReader, but an open reader may cause the conn.Close() the have no effect.
If the reader is open, this means that the records and tables read by sProc_Elines_Send_GetContentPending are probably locked, which means that the locks are not released, even though the records are not accessed any more.
You should also have a look at the Using statement (see this question) to handle connections, commands, and readers.
Further, you have a While loop, but only process a single record. And if the Reader does not return a record, you end up with a lot of uninitialized variables. But that's not related to your locking problem.
The query looks fine, and if you have less than 1k rows, I don't know why it would end up timing out.
One thing you could try is to add a variable at the top, and add CAST(GETDATE() AS smalldatetime) into that. Then use the variable in your update.
DECLARE #myDate smalldatetime AS CAST(GETDATE() AS smalldatetime)
UPDATE tblElinesNewsletter
SET
NewsletterSent = 1,
DateSent= myDate ,
ApprovalPending = 0
WHERE NewsletterSent = 0
I'm not sure it'll do anything, but the idea is to store the value of the date in a constant, rather than have it evaluated in the WHERE clause.
All:
First off, thank you for your help/assistance. This was really the first time I've used this board with such an extensive issue. I wish I could awared ALL responses, as they all helped to paint a clearer picture of what was going on.
I solved the issue in part by what Devio said about connections not being closed. Digging into the .NET page further, I found that there was a Session State database call that managed the security of the page. This was coming from an iframe tag and actually on a DIFFERENT page using the same connection string and database. Apparently this connection string did NOT close and remained open with the same database and same overall table. Then the sProc_Elines_Send_GetContentPending proc tried to run -- which it appeared to do, as did the sProc_SendElines proc. However when the sProc_Elines_Send_MarkComplete proc tried to run, it failed as I mentioned eariler.
When I rewrote the database connection code to add to following statements:
Cmd.ExecuteNonQuery()
Conn.Close()
Conn.Dispose()
It then closed the security Session State database connection, which then allowed all three of the other stored procedures to run.
So again, this resolved the issue and the genesis of figuring it out for me was from Devio's close connection suggestion.
I hope I did this question closure with the correct Stack Overflow protocol and please let me know if I missed anything. Thanks again everyone. You are the best!
-- Chris

Restore database in SQL LocalDB using VB.NET

I have a project developed in VB.NET and SQL Server 2012 LocalDB (v11) and I am need backup/restore facility in my application. Backup part is complete but I am stuck at restore part. This is the query I want to be worked (and its working fine in SQL Editor)
ALTER DATABASE [<.MDF File Path>]
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [<.MDF File Path] FROM DISK='<.bak File Path'
and here is the code in VB.NET I am trying to execute
Sub Restorequery(ByVal que As String)
MainForm.Conn.Close()
con = New SqlConnection("Data Source=(LocalDB)\v11.0;Database=Master;integrated security=True;")
If Not con.State = ConnectionState.Open Then con.Open()
cmd = New SqlCommand(que, con)
cmd.ExecuteNonQuery()
End Sub
And here are the approaches I tried so far
Using the same query as above
Restorequery("ALTER DATABASE [<.MDF File Path>] SET SINGLE_USER WITH ROLLBACK IMMEDIATE")
Restorequery("restore database [<.MDF File Path>] from disk='<.bak File Path>'")
and this results in an error
Exclusive access could not be obtained because the database is in use. RESTORE DATABASE is terminating abnormally.
After finding reason for above issue (which is nonsense even after using master database while opening connection and closing all the previously opened connections using MainForm.Conn.Close() ), I tried second approach as per some links and references from Stackoverflow. And here are the queries I tried:
Restorequery("use [master] ")
Restorequery("alter database [<.MDF File Name>] set single_user with rollback immediate")
Restorequery("restore database[<.MDF File Name>] from disk='<.bak File Name>'")
Restorequery("alter database [<.MDF File Name>] set multi_user")
Restorequery("use [<.MDF File Name>]")
and here is the error I got while executing second query :
Additional information: User does not have permission to alter database <.MDF File Name with Path>, the database does not exist, or the database is not in a state that allows access checks. ALTER DATABASE statement failed.
Is there any other way to restore a SQL Server LocalDB using VB.NET ?
I have Used this code in one of my project.
Try
With OpenFileDialog1
.Filter = ("DB Backup File|*.bak;")
.FilterIndex = 4
End With
OpenFileDialog1.FileName = ""
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
Cursor = Cursors.WaitCursor
SqlConnection.ClearAllPools()
con = New SqlConnection(cs)
con.Open()
Dim cb As String = "USE Master ALTER DATABASE [" & System.Windows.Forms.Application.StartupPath & "\BRH.mdf] SET Single_User WITH Rollback Immediate Restore database [" & System.Windows.Forms.Application.StartupPath & "\BRH.mdf] FROM disk='" & OpenFileDialog1.FileName & "' WITH REPLACE ALTER DATABASE [" & System.Windows.Forms.Application.StartupPath & "\BRH.mdf] SET Multi_User "
cmd = New SqlCommand(cb)
cmd.Connection = con
cmd.ExecuteReader()
con.Close()
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try