When I want to get the definition of a stored procedure (in SQL Server) I use SQL Server Management Studio.
I sometimes run the `sp_helptext' to output the definition of a stored procedure.
Link: https://msdn.microsoft.com/en-us/library/ms176112.aspx
In a nutshell, I'd like to have a simple html popup window that would output any stored procedure's definition to text.
The asp code below is making a successful connection to my Database, but I'm not getting any output.
<%
' .......
sql = "exec sp_helptext 'some_ProcName_Here'"
objRs.open sql, objConn
Text=objRs("Text")
response.write(Text)
%>
I also attempted creating a new Stored Procedure that takes 1 parameter, which would execute the sp_helptext.
<%
' .......
sql = "exec See_Proc_Definition #ProcName=some_ProcName_Here"
objRs.open sql, objConn
Text=objRs("Text")
response.write(Text)
%>
Neither of these display anything, but I don't get any returned errors neither.
Can anyone see what I'm doing wrong?
The problem is you are only displaying the first line of the sp_HelpText output. SQL Server returns the output as a single column recordset containing a column called [Text].
This means you need to iterate through the rows to display the rest of the output.
Using your first example;
<%
' .......
sql = "exec sp_helptext 'some_ProcName_Here'"
objRs.open sql, objConn
Do While Not objRs.EOF
Text=objRs("Text")
response.write(Text)
objRS.MoveNext
Loop
%>
This isn't ideal but will work, from experience (especially with more complex stored procedures) I find something like this is better in the long run;
Dim sql, cmd, rs, data
Set cmd = Server.CreateObject("ADODB.Command")
sql = "sp_HelpText"
With cmd
'Use your connection string instead of instantiating an ADODB.Connection object.
.ActiveConnection = conn_string
.CommandType = adCmdStoredProc
.CommandText = sql
.Parameters.Append(.CreateParameter("#objname", adVarWChar, adParamInput, 776))
.Parameters.Append(.CreateParameter("#columnname", adVarWChar, adParamInput, 128))
Set rs = .Execute(, Array("some_ProcName_Here"))
If Not rs.EOF Then data = rs.GetRows()
Call rs.Close()
Set rs = Nothing
End With
Set cmd = Nothing
This method gives you a 2-Dimensional Array containing the row data in the data variable. You can then use standard Array techniques to manipulate the output.
Dim output, row, rows
If IsArray(data) Then
rows = UBound(data, 2)
For row = 0 To rows
output = output & "<br />" & data(0, row)
Next
Call Response.Write(output)
End If
Links
Using METADATA to Import DLL Constants - If your having trouble with the ADO constants (adCmdStoredProc etc.) this will fix it for you.
Related
I created many spreadsheets which use stored procedures. I have a custom VBA code which works fine when I try to get data from SQL. However, today I wanted to execute parametrized stored procedure which inserts and updates data on a database table. When I run macro no errors show up, however there's no insert/update action on database. I have no idea why. I established SQL connection in my workbook (myConn) as I do everytime I need to connect with SQL so it's correct for sure. This is my standard VBA code:
Sub SaveData()
Dim myValue As Double
myValue = Sheets("XYZ").Range("valueToSave").Value
With ActiveWorkbook.Connections("myConn").OLEDBConnection
.CommandText = Array( _
"EXEC DB.[dbo].[myProc] '" & myValue & "'")
End With
ActiveWorkbook.Connections("myConn").Refresh
End Sub
I need to insert data into column of decimal(6,4) type (in SQL table). myProc does it perfectly when I run it manually via SSMS but not here using VBA code. valueToSave is an Excel range which stores one decimal value (for example: 23,56, 11,21 etc.). When I run macro nothing happens. When I run macro and go to 'Connection Properties' > 'Definitions' > 'Command Text' then I can see there's a procedure with parameter (EXEC DB.[dbo].[myProc] '11,23'). So my acode above seems working but not executing stored procedure.
Has it something to do with data type? Honestly, I tried with other VBA types: String, Variant, Integer but it's not working. I also changed data type of that column in SQL table (to varchar, int etc.) but it also doesn't work. The most interesting thing is that the code above works fine when I withdraw data from db, it doesn't work when need to insert/update data.
PS. I guess I added all required refrences:
Using ADODB
Option Explicit
Sub SaveData()
Const PROC_NAME = "DB.dbo.myproc"
Dim wb As Workbook
Dim ado As ADODB.Connection, cmd As ADODB.Command
Dim sCon As String, v As Single
Set wb = ThisWorkbook
v = wb.Sheets("XYZ").Range("valueToSave").Value
' get connection string
sCon = wb.Connections("myConn").OLEDBConnection.Connection
sCon = Replace(sCon, "OLEDB;", "")
' open connection
Set ado = New ADODB.Connection
ado.Open sCon
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = ado
.CommandType = adCmdStoredProc
.CommandText = PROC_NAME
.Parameters.Append .CreateParameter("P1", adDecimal, adParamInput)
With .Parameters(0)
.NumericScale = 2
.Precision = 18
.Value = v
End With
.Execute
End With
ado.Close
MsgBox PROC_NAME & " " & v, vbInformation, "Done"
End Sub
Iam running a legacy VB6 application. I'm trying to execute a stored procedure that would go through a bunch of tables in SQL-SERVER, grab Data and put it into a table in SQL - SERVER. Do I need to declare and set a new recordset?
dim strSQL as string
strSQL = "Exec FillEmptyTable #blah = "& blah
It would seem that I don't need a recordset, but this doesn't execute
Now when i SET a new recordset, then it works
dim rs as adodb.recordset
set rs = new adodb.recordset
dim strSQL as string
strSQL = "Exec FillEmptyTable #blah = "&blah
rs.open strSQL, Connection
Is this right? I don't know why I need a recordset if I'm only creating one on SQL-SERVER side?
If you don't need a recordset because the SP returns no rows or you don't care about any rows it does return you can simply pass the SQL string to the connection object:
Connection.Execute strSQL, 0, adCmdText
See here for a more formal way using a Command object that removes potential the SQL injection vulnerabilities implicit in manually building SQL in a string.
I have an Access DB that has a bunch of linked tables from a SQL Server database. The Access DB calls a stored procedure on the SQL Server database that updates data on a form.
Dim sql As String
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
cnn.ConnectionString = "DSN=Records"
cnn.CommandTimeout = 90
cnn.Open
sql = "exec myStoredProcedure #param1=" & Me.txtParam1Field & ", #param2=" & Me.txtParam2Field
cnn.Execute sql
Set cnn = Nothing
frmMyForm.Requery
When I run this it either times out, if the CommandTimeout value isn't long enough, or it executes, but doesn't actually execute myStoredProcedure for some reason. If I take the string sql and past it into Sql Server Manager, myStoredProcedure executes in less than a second and everything works great.
I've tried debugging over this code in Access, but I'm not getting any useful results when I step over cnn.Execute sql.
Depending on the values of txtParam1Field and txtParam2Field you probably want to enclose the values with single quote like so:
sql = "exec myStoredProcedure #param1='" & Me.txtParam1Field & "', #param2='" & Me.txtParam2Field & "'"
If we take your original code and assume that txtParam1Field is equal to 1 and txtParam2Field is equal to John then your generated sql will not execute because it will look like this:
exec myStoredProcedure #param1=1, #param2=John
Your best bet is to output the value of "sql" variable in debug window and run that exact statement in sql query manager. That will tell you exactly where the problem is if it's malformed SQL.
You could try setting the Prepared property to false on the command object. This causes a recompile of the procedure before execution, but could result in a better plan depending on the parameters that are sent.
Dim sql As String
Dim cnn As ADODB.Connection
Dim Cmd As ADODB.Command
Set cnn = New ADODB.Connection
cnn.ConnectionString = "DSN=Records"
cnn.CommandTimeout = 90
cnn.Open
sql = "exec myStoredProcedure #param1=" & Me.txtParam1Field & ", #param2=" & Me.txtParam2Field
Set Cmd = New ADODB.Command
Set Cmd.ActiveConnection = cnn
Cmd.CommandType = adCmdText
Cmd.CommandText = sql
Cmd.Prepared = False
Cmd.CommandTimeout = 300
Cmd.Execute
I'm trying to fill a continuous form in access 2013 using data from a stored procedure in ms sql server 2014. The database connection works, I can use other access forms to add data to the ms sql server database. So that's not the problem.
Here's my stored procedure:
CREATE PROCEDURE spArtikelen AS
BEGIN
SELECT a.artikelnr, omschrijving, v.voorraad, p.prijs, a.leverancier
FROM artikel AS a, artikelprijs AS p, artikelvoorraad AS v
WHERE a.artikelnr = p.artikelnr
AND a.artikelnr = v.artikelnr
AND CAST(GETDATE() AS DATE) BETWEEN p.begindatum AND p.einddatum
END
And here's my vba code (I put the vba code on the LOAD event of the form):
Private Sub Form_Load()
Dim rs As ADODB.Recordset
Set rs = DbConn.Execute("EXEC spArtikelen")
Do Until rs.EOF
Me.txtArtikelnr.Value = rs!artikelnr
Me.txtOmschrijving.Value = rs!omschrijving
Me.txtVoorraad.Value = rs!voorraad
Me.txtPrijs.Value = rs!prijs
Me.txtLeverancier.Value = rs!leverancier
Debug.Print rs!artikelnr, rs!omschrijving, rs!voorraad, rs!prijs, rs!leverancier
rs.MoveNext
Loop
End Sub!
the continuous form..
How do I fix this? I've been trying to get it work all day.. without success..
Every time I run the form, I only get one record, and I can't click through the records.!
Here's the data from the stored procedure I'm trying to put into the form.
Possible solution?
Open your recordset with adUseClient for its CursorLocation property. Then set the form's Recordset property to your ADO recordset.
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open "EXEC spArtikelen", DbConn
Set Me.Recordset = rs
Then with artikelnr for txtArtikelnr.ControlSource, omschrijving for txtOmschrijving.ControlSource, and so forth the form should load with the recordset rows as you wish.
Note the data displayed within the form will be read-only. Hopefully that is not an unwelcome surprise.
Also, I suggested this approach because you already had a suitable ADO recordset. However, I think Gord's suggestion to use a pass-through query as your form's RecordSource is simpler.
Stored procedure, and using ADO to connect, i'm having problems with the quotes however..
x = "text'"
If instr(x,"'") then x=replace(x,"'","''")
'x = "text''" at this point
Set Rs = Server.Createobject("adodb.recordset")
Rs.Open "Select_SP #name='" & x & "'"
I thought i was doing this right.. But I guess not, because i'm getting this error:
Microsoft OLE DB Provider for SQL Server error '80040e14'
SELECT ID from Table where Name='text''
Shouldn't it be
Name = 'text'''
Why isn't SQL recognizing the double quotes using ADO?
The Select_SP Uses something like this:
SET #sql = 'SELECT ID from Table where Name='''+#name+''''
Exec(#sql)
Do I have this SP written correctly?
The short answer is, don't call procedures the way you're doing it. Use a Command instead. This is from memory, since I don't have a Windows system in front of me at the moment, but it should work:
Dim cmd
Set cmd = Server.CreateObject("ADODB.Command")
Set Cmd.ActiveConnection = myConnectionVariableHere
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "Select_SP"
'Note: if the above two lines don't work, replace them with the following
'cmd.CommandType = adCmdText
'cmd.CommandText = "Select_CP #name=?"
cmd.Parameters.Append cmd.CreateParameter("name", adVarChar, adParamInput, len(x), x)
Rs.Open cmd
Now, all that said, I can't tell you why your procedure is giving that particular output since you're not showing us the code for it. But I'm fairly certain ADO isn't going to convert a pair of single quotes into a double quote - not sure why you'd expect it to.
Edit after seeing the OP's edit. Don't execute SQL that way unless you absolutely have to. You will only give yourself grief. I don't know what database you're using and that procedure syntax doesn't look familiar, but in Oracle you could write something like:
PROCEDURE sql_test(MyName IN VARCHAR2, MyCursor OUT SYS_REFCURSOR) IS
BEGIN
OPEN MyCursor FOR SELECT id FROM some_table WHERE name = MyName;
END;