Stored Procedure not updating database - stored-procedures

Issue:
The database is not updating but I'm unsure where it drops.
I've used numerous ones in the past but I can't see why this is not working. If I could see how to run an error test on the stored procedure I suspect that would help.
Tests:
I pass the variables to a label, after the stored procedure request in the .aspx code to check the values exist (left in code)
Change int to varchar in the stored procedure
Query:
How do I fix this and then how can I run tests to find the issues in the future
Stored Procedure:
USE [DATABASE]
GO
/****** Object: StoredProcedure [dbo].[spChangeValue] Script Date: 11/08/2015 12:02:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
ALTER PROCEDURE [dbo].[spRiskRatingChange]
#ActionID int,
#EmployeeID int,
#NewRating varchar(10)
AS
DECLARE #DateChanged AS nvarchar(max)
SET #DateChanged = GETDATE()
DECLARE #OldRating AS nvarchar(max)
DECLARE #OldComments AS nvarchar(max)
DECLARE #EmployeeName AS nvarchar(max)
SET #OldRating =
(
SELECT OverallRiskCategory FROM TblAsbestos WHERE ID = #ActionID
)
SET #OldComments =
(
SELECT Comments FROM TblAsbestos WHERE ID = #ActionID
)
SET #EmployeeName =
(
SELECT UserFirstName + ' ' + UserSurname FROM SystemUsers WHERE ID = #EmployeeID
)
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE TblAsbestos SET OverallRiskCategory = #NewRating, RiskCategory = #NewRating,
Comments= ('Rating changed from ' + RTRIM(#OldRating) + ' to '
+ RTRIM(#NewRating) + 'By ' + #EmployeeName + ' on ' + #DateChanged + ' -- ' + #OldComments)
WHERE ID = #ActionID
END
Code in .aspx.vb
Dim connection As SqlConnection
Dim command As New SqlCommand
Dim ds As New DataSet
Dim ConnectionString1 As String = System.Configuration.ConfigurationManager.ConnectionStrings("VINCI_SQL").ToString()
connection = New SqlConnection(ConnectionString1)
connection.Open()
With command
.Connection = connection
.CommandText = "spRiskRatingChange" 'include audit names
.CommandType = CommandType.StoredProcedure
.Parameters.Clear()
.Parameters.AddWithValue("#ActionID", Session("ActionID").ToString)
.Parameters.AddWithValue("#EmployeeID", Session.Item("EmployeeID").ToString)
.Parameters.AddWithValue("#NewRating", ddOverallRiskCategoryEdit.SelectedValue)
.ExecuteNonQuery()
lblErrorMessageRatings.Visible = True
lblErrorMessageRatings.Text = "Action ID: " & Session("ActionID").ToString
lblErrorMessageRatings.Text = lblErrorMessageRatings.Text & " EmployeeID: " & Session("EmployeeID").ToString
lblErrorMessageRatings.Text = lblErrorMessageRatings.Text & " NewRating: " & ddOverallRiskCategoryEdit.SelectedValue
Read items such as:
UPDATE Stored Procedure not Updating

Instead of
.Parameters.AddWithValue("#ActionID", Session("ActionID").ToString)
try
.Parameters.Add("#ActionId",SqlDbType.Int)
.Parameters("#ActionId").Value = CInt(Session("ActionId"))
I am assuming it is an int value you are passing
.Parameters.AddWithValue does an implicit type conversion and perhaps this is what is causing your problem

Related

ASP Classic Recordset In Stored Procedure -1 Recordcount

I'm working with a SQL Server stored procedure in Classic ASP with 3 parameters. I am attempting to find the recordcount, but it returns '-1'.
I saw a similar post, did what it suggested (check cursortype, and add 'set nocount on' in the stored procedure), but those changes did not impact the -1 recordcount.
Here is my code in the Classic ASP page, below.
strInterestName = request("InterestName")
strActiveDate = request("activedate")
strExpireDate = request("expiredate")
Set objCommandSec = CreateObject("ADODB.Command")
Set objRS = CreateObject("ADODB.RecordSet")
objRS.cursorlocation = 3
objRS.cursortype = adOpenStatic
With objCommandSec
Set .ActiveConnection = objConnection
.CommandText = "[01_cms_search_pg_select_news_items_4]"
.CommandType = 4
.Parameters.Append .CreateParameter("#InterestName",adVarChar,
adParamInput, 25)
.Parameters.Append .CreateParameter("#ActiveDate",adDate, adParamInput)
.Parameters.Append .CreateParameter("#ExpireDate",adDate,
adParamInput)
.Parameters("#InterestName") = strInterestName
.Parameters("#ActiveDate") = strActiveDate
.Parameters("#ExpireDate") = strExpireDate
set objRS =.Execute()
End With
Here is the code for the stored procedure, below:
ALTER PROCEDURE [dbo].[01_cms_search_pg_select_news_items_4]
#InterestName varchar(50),
#ActiveDate datetime,
#ExpireDate datetime
AS DECLARE #sql nvarchar(4000)
SELECT #sql = ' SELECT * ' +
' FROM news ' +
' WHERE ' +
' bulletin_display_indicator = ''true'' '+
' AND ' +
' website_homepg_display_indicator= ''false'' '
IF #InterestName is not null
SELECT #sql = #sql + ' AND (InterestName = #InterestName)
IF #ExpireDate is not null and #ExpireDate IS NOT NULL
SELECT #sql = #sql + ' AND (expiredate between #ActiveDate and #ExpireDate)
SELECT #sql = #sql + '; '
EXEC sp_executesql #sql, N'#InterestName varchar(50), #ActiveDate
DateTime, #ExpireDate DateTime',#InterestName, #ActiveDate,
#ExpireDate
I struggled with that for a while, then found something that works for me.
It's not pretty but it does the job.
Have your Stored Procedure return 2 recordsets: one with the table data you need followed by one with the recordcount:
SELECT <all_you_need> FROM <your_table> WHERE <your_arguments>
SELECT [myCount] = ##ROWCOUNT
Then, in your ASP file:
dim objRS, dataRS, countRS
Set objRS = CreateObject("ADODB.RecordSet")
Set dataRS = CreateObject("ADODB.RecordSet")
Set countRS = CreateObject("ADODB.RecordSet")
[your original call to the stored procedure]
set objRS =.Execute()
set dataRS = objRS
set countRS = objRS.nextrecordset()
countRS now contains a recordset with a single row and a single column named 'myCount' that you can query to get the recordcount.
dataRS contains your original dataset.
NOTE: if you don't need to know the recordcount BEFORE you process the dataset, you can simplify like this:
dim objRS, countRS
Set objRS = CreateObject("ADODB.RecordSet")
Set countRS = CreateObject("ADODB.RecordSet")
[your original call to the stored procedure]
set objRS =.Execute()
[process your dataset as you need to]
set countRS = objRS.nextrecordset()

OUTPUT variables to sp_executesql

Background: SQL Server 2008 R2
Having issues with the following. Been given a usp to "finish off", author is unavailable. It extracts data from source table, copies to target table of same name + datetime stamp in an archive db then truncates source table. Want to confirm that no errors have occurred & row counts are the same before I truncate source. As I'm using DDL a TRY CATCH combo won't work.
Following code works:
DECLARE #HostName VARCHAR(30) -- Name of server running script
DECLARE #dbName VARCHAR(30) -- Database currently connected to
DECLARE #LogText VARCHAR(255) -- Text to be logged to ArchLog table
DECLARE #NewUTMetaData VARCHAR(255) -- New tablename for UTMetaData
DECLARE #NewOutboundMessagePending VARCHAR(255) -- New tablename for OutboundMessagePending
DECLARE #NewOutboundMessageStatus VARCHAR(255) -- New tablename for OutboundMessageStatus
DECLARE #NewOutboundMessageResult VARCHAR(255) -- New tablename for OutboundMessageResult
DECLARE #NewFileMessageNonSequence VARCHAR(255) -- New tablename for FileMessageNonSequence
DECLARE #NewOutboundMessageRequest VARCHAR(255) -- New tablename for OutboundMessageRequest
DECLARE #NewOutboundMessage VARCHAR(255) -- New tablename for OutboundMessage
DECLARE #SQLQuery NVARCHAR(500)
DECLARE #return_value INT
DECLARE #Err INT = 0
DECLARE #ErrFin INT = 0
DECLARE #SQLCount NVARCHAR(255) = 'SELECT #TargetCountOUT = COUNT(*) FROM '
DECLARE #ParmDefinition nvarchar(50) = N'#TargetCountOUT int OUTPUT';;
DECLARE #SourceCount INT = 0
DECLARE #TargetCount INT = 0
-- Log message that delete is starting
SELECT #HostName = host_name()
SELECT #dbName = db_name()
SELECT #LogText = 'Procedure ArchiveMuleDBMetrix_NEW starting database= ' + #dbname + ' host= ' + #HostName
EXEC xp_logevent 50001, #LogText, 'INFORMATIONAL'
INSERT INTO [MuleDBArch].[dbo].[ArchLog]
([LogEntryDateTime]
,[LogEntry])
VALUES (GETDATE()
,#LogText)
BEGIN
SELECT #NewUTMetaData = (SELECT '[MuleDBArch].[dbo].UTMetaDataA' + convert(varchar(50),GetDate(),112) + replace(convert(varchar, GetDate(),108),':',''))
SET #err = ##error;
SET #SQLQuery = 'select * into ' + #NewUTMetaData + ' from [MuleDB].[dbo].[SASITUTMetaData]'
EXECUTE sp_executesql #SQLQuery
SET #SourceCount = ##ROWCOUNT
SELECT #LogText = 'Rows archived into ' + #NewUTMetaData + ' by Procedure ArchiveMuleDBMetrix_NEW = ' + CAST(#SourceCount as VARCHAR(6))
EXEC xp_logevent 50002, #LogText, 'INFORMATIONAL'
INSERT INTO [MuleDBArch].[dbo].[ArchLog]
([LogEntryDateTime]
,[LogEntry])
VALUES (GETDATE()
,#LogText)
IF #err = 0
BEGIN
SET #sqlcount = #sqlcount + #NewUTMetaData
EXECUTE sp_executesql #sqlcount, #ParmDefinition, #TargetCountOUT=#TargetCount OUTPUT;
IF #SourceCount = #TargetCount
TRUNCATE TABLE [MuleDB].[dbo].[SASITUTMetaData]
ELSE
SELECT #LogText = 'Post archive, row counts differ between [MuleDB].[dbo].[SASITUTMetaData] and' + #NewUTMetaData
EXEC xp_logevent 50003, #LogText, 'Error'
Set #errfin = 1
SET #err = 0
END
ELSE
BEGIN
SELECT #LogText = 'Procedure ArchiveMuleDBMetrix_NEW failed archiving into ' + #NewUTMetaData
EXEC xp_logevent 50004, #LogText, 'Error'
Set #errfin = 1
SET #err = 0
END
END
However, if I repeat the block to work on another table (or indeed the same one) query completes with error and I get the message:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '.'.
I think I've narrowed it down to the line:
EXECUTE sp_executesql #sqlcount, #ParmDefinition, #TargetCountOUT=#TargetCount OUTPUT;
Any help appreciated
In the below code
EXECUTE sp_executesql #sqlcount, #ParmDefinition, #TargetCountOUT=#TargetCount OUTPUT;
You are trying to pass parameter values without specifying the parameter names except the output parameter while calling the stored procedure. Either specify the parameter name for all or none. Try to execute the code as follows
EXECUTE sp_executesql #sqlcount, #ParmDefinition, #TargetCount OUTPUT;

How to read quoted field from CSV using VBScript

In a sample.csv file, which has fixed number of columns, I have to extract a particular field value and store it in a variable using VBScript.
sample.csv
100,SN,100.SN,"100|SN| 435623| serkasg| 15.32|
100|SN| 435624| serkasg| 15.353|
100|SN| 437825| serkasg| 15.353|"," 0 2345"
101,SN,100.SN,"100|SN| 435623| serkasg| 15.32|
100|SN| 435624| serkasg| 15.353|
100|SN| 437825| serkasg| 15.353|"," 0 2346"
I want to parse the last two fields which are within double quotes and store them in two different array variables for each row.
You could try using an ADO connection
Option Explicit
dim ado: set ado = CreateObject("ADODB.Connection")
ado.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\txtFilesFolder\;Extended Properties=""text;HDR=No;FMT=Delimited"";"
ado.open
dim recordSet: set recordSet = ado.Execute("SELECT * FROM [samples.csv]")
dim field3, field4
do until recordSet.EOF
field3 = recordSet.Fields(3).Value
field4 = recordSet.Fields(4).Value
' use your fields here
recordSet.MoveNext
loop
recordSet.close
ado.close
You may have an issue if those fields are greater than 255 characters in length - if they are, they may return truncated. You also may have better luck with ODBC or ACE connection strings instead of the Jet one I've used here.
Since CSV's are comma-separated, you can use the Split() function to separate the fields into an array:
' Read a line from the CSV...
strLine = myCSV.ReadLine()
' Split by comma into an array...
a = Split(strLine, ",")
Since you have a static number of columns (5), the last field will always be a(4) and the second-to-last field will be a(3).
Your CSV data seems to contain 2 embedded hard returns (CR, LF) per line. Then the first line ReadLine returns is:
100,SN,100.SN,"100|SN| 435623| serkasg| 15.32|
The solution below unwraps these lines before extracting the required fields.
Option Explicit
Const ForReading = 1
Const ForAppending = 8
Const TristateUseDefault = 2 ' Opens the file using the system default.
Const TristateTrue = 1 ' Opens the file as Unicode.
Const TristateFalse = 0 ' Opens the file as ASCII.
Dim FSO, TextStream, Line, LineNo, Fields, Field4, Field5
ExtractFields "sample.csv"
Sub ExtractFields(FileName)
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(FileName) Then
Line = ""
LineNo = 0
Set TextStream = FSO.OpenTextFile(FileName, ForReading, False, TristateFalse)
Do While Not TextStream.AtEndOfStream
Line = Line & TextStream.ReadLine()
LineNo = LineNo + 1
If LineNo mod 3 = 0 Then
Fields = Split(Line, ",")
Field4 = Fields(3)
Field5 = Fields(4)
MsgBox "Line " & LineNo / 3 & ": " & vbNewLine & vbNewLine _
& "Field4: " & Field4 & vbNewLine & vbNewLine _
& "Field5: " & Field5
Line = ""
End If
Loop
TextStream.Close()
Else
MsgBox "File " & FileName & " ... Not found"
End If
End Sub
Here is an alternative solution that allows for single or multiline CSV records. It uses a regular expression which simplifies the logic for handling multiline records. This solution does not remove CRLF characters embedded in a record; I've left that as an exercise for you :)
Option Explicit
Const ForReading = 1
Const ForAppending = 8
Const TristateUseDefault = 2 ' Opens the file using the system default.
Const TristateTrue = 1 ' Opens the file as Unicode.
Const TristateFalse = 0 ' Opens the file as ASCII.
Dim FSO, TextStream, Text, MyRegExp, MyMatches, MyMatch, Field4, Field5
ExtractFields "sample.csv"
Sub ExtractFields(FileName)
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(FileName) Then
Set MyRegExp = New RegExp
MyRegExp.Multiline = True
MyRegExp.Global = True
MyRegExp.Pattern = """([^""]+)"",""([^""]+)"""
Set TextStream = FSO.OpenTextFile(FileName, ForReading, False, TristateFalse)
Text = TextStream.ReadAll
Set MyMatches = MyRegExp.Execute(Text)
For Each MyMatch in MyMatches
Field4 = SubMatches(0)
Field5 = SubMatches(1)
MsgBox "Field4: " & vbNewLine & Field4 & vbNewLine & vbNewLine _
& "Field5: " & vbNewLine & Field5, 0, "Found Match"
Next
Set MyMatches = Nothing
TextStream.Close()
Else
MsgBox "File " & FileName & " ... Not found"
End If
End Sub

Classic ASP - ADO execute Stored Procedure passing in parameters

I am needing to pass parameters into a stored procedure with Classic ASP. I do see some people using the Command object and others NOT using it.
My sproc params are like this:
#RECORD_NUMBER decimal(18,0),
#ErrorType nvarchar(100),
#INSURANCE_CODE smallint,
#CompanyId int,
#INS_ID_NUM nchar(22)
Then I'm trying to do this:
Dim conn, rsSet,rsString, cmd
Dim RN,ET,IC,CI,IIN
RN = Request.Form("Record_Number")
ET = Request.Form("ErrorType")
IC = Request.Form("INSURANCE_CODE")
CI = Request.Form("CompanyID")
IIN = Request.Form("INS_ID_NUM")
set conn = server.CreateObject("adodb.connection")
set rsSet = Server.CreateObject ("ADODB.Recordset")
conn.Open Application("conMestamed_Utilities_ConnectionString")
rs_string = "apUpdateBill " & RN &",'" & ET & "'," & IC & "," & CI & ",'" & IIN & "'"
rsSet.Open rsString, conn, adOpenForwardOnly,, adCmdText
(I don't need a Recordset, i'm just trying to get it to send in data)
Error:
ADODB.Recordset error '800a0bb9'
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
I have tried Command stuff and I get "precision" errors
Do I "have" to use command object?
e.g.
Set cmd = Server.CreateObject("ADODB.Command")
'Set cmd.ActiveConnection = conn
'cmd.CommandText = "apUpdateBill"
'cmd.CommandType = adCmdStoredProc
'Cmd.Parameters.append Cmd.createParameter("#Record_Number", adDecimal, adParamInput, 18)
'Cmd.Parameters("#Record_Number").Precision = 0
'Cmd.Parameters("#Record_Number").value = Request.Form("Record_Number")
Here is how you would do it, you won't need to create a recordset object since it is an update stored procedure:
'Set the connection
'...............
'Set the command
DIM cmd
SET cmd = Server.CreateObject("ADODB.Command")
SET cmd.ActiveConnection = Conn
'Prepare the stored procedure
cmd.CommandText = "apUpdateBill"
cmd.CommandType = 4 'adCmdStoredProc
cmd.Parameters("#RECORD_NUMBER") = Request.Form("Record_Number")
cmd.Parameters("#ErrorType") = Request.Form("ErrorType")
cmd.Parameters("#INSURANCE_CODE") = Request.Form("INSURANCE_CODE")
cmd.Parameters("#CompanyId") = Request.Form("CompanyID")
cmd.Parameters("#INS_ID_NUM") = Request.Form("INS_ID_NUM")
'Execute the stored procedure
'This returns recordset but you dont need it
cmd.Execute
Conn.Close
SET Conn = Nothing

ADODB.Recordset error '800a0e78' - Error when I pass 2 parameters (ASP/MSSQL)

My classic ASP page thorws up an error when I pass 2 paremeters to the Exec code for my
stored procedure. Basically I want to send 1 paremeter to cover the column I am looking for
and one for the search-term. For example imSchool, New York University. I have data checks on the data sent as well as Record Set.State code showing that everytime i choose SQL Query with the two paramerts the error "Operation is not allowed when the object is closed." always shows.
I tried to open the object at " While Not rs.EOF" line of code where it error out bit no luck.
I am thinking my SQLQuery is bad because when I run the Stored Procedure in MSSQL with the same input I get a return table everytime. SQL Server 2008 R2 and Classic ASP.
HERE IS MY IF STATMENT WITH SQLQUERY CODE (keep in mind the 1st one works fine and data is selected from the DB)
SQLQuery = "Exec sp_vw_InternImport"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.CursorType = 3
rs.Open SQLQuery, OBJdbConnection
If filterColmn <> "" Then
SQlQuery = "Exec sp_vw_InternImport_ColID #LookUpID=N'" + filterID + "'" + ", #LookUpCol=N'" + filterID + "'"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.CursorType = 3
rs.Open SQLQuery, OBJdbConnection
End If
HERE IS MY STORED PROCEDURE CODE
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_vw_InternImport_ColID]
(
#LookUpID nvarchar (255),
#LookUpCol nvarchar (50)
)
AS
SET NOCOUNT ON
BEGIN
IF #LookUpCol = 'imYear'
SELECT * FROM v_InternImport WHERE imYear = #LookUpID
ELSE
IF #LookUpCol = 'imSchool'
SELECT * FROM v_InternImport WHERE imSchool = #LookUpID
ELSE
IF #LookUpCol = 'imDiscipline'
SELECT * FROM v_InternImport WHERE imDiscipline = #LookUpID
IF #LookUpCol = 'imDegree'
SELECT * FROM v_InternImport WHERE imDegree = #LookUpID
END
When passing arguments to stored procedure directly, you don't have to "assign" the parameters. Doing this probably results in the whole value passed (e.g. #LookUpCol will have the value of #LookUpCol ='imYear') thus your SP won't select anything and you have empty and closed recordset.
Try having such code instead:
SQlQuery = "Exec sp_vw_InternImport_ColID '" & filterID & "', '" & filterID & "'"
You can't use the same object twice at the same time (like rs), you have to make it another name or you have to close it and start over.. This should work:
SQLQuery = "Exec sp_vw_InternImport"
If filterColmn <> "" Then SQLQuery = "Exec sp_vw_InternImport_ColID #LookUpID=N'" + filterID + "'" + ", #LookUpCol=N'" + filterID + "'"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.CursorType = 3
rs.Open SQLQuery, OBJdbConnection
rs.Close
Or in your example, if you close the first rs object before you go on to the next, it may help.
set rs = nothing ... then .... set rs = server.createobject
So like this:
SQLQuery = "Exec sp_vw_InternImport"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.CursorType = 3
rs.Open SQLQuery, OBJdbConnection
rs.Close ------ Close it before you re-open it
If filterColmn <> "" Then
SQlQuery = "Exec sp_vw_InternImport_ColID #LookUpID=N'" + filterID + "'" + ", #LookUpCol=N'" + filterID + "'"
rs.Open SQLQuery, OBJdbConnection
rs.Close ------ Always Close your Objects!
End If

Resources