A very simple function:
CREATE OR REPLACE FUNCTION stzh.test() RETURNS refcursor AS $BODY$
declare
outcursor refcursor;
begin
OPEN outcursor
FOR SELECT '-1' As "value1";
return outcursor;
end;$BODY$
LANGUAGE plpgsql
Code to call the function:
Dim pCon As NpgsqlConnection
Dim pCommand As NpgsqlCommand
Dim pDataReader As IDataReader
pCon = New NpgsqlConnection(System.Configuration.ConfigurationManager.AppSettings("PG_connection"))
pCon.Open()
pCon.BeginTransaction()
pCommand = pCon.CreateCommand
With pCommand
.CommandText = "stzh.test"
.CommandType = CommandType.StoredProcedure
pDataReader = .ExecuteReader
End With
While pDataReader.Read
Console.WriteLine(pDataReader.GetName(0))
End While
Executing this code writes the name of the function ("test") to the console. I was expecting the name of the column ("value1") to be written to the console.
What am I missing?
Related
I am writing a web service function in VB.net in a stored procedure in SQL server. I think the DataReader does not return any value.
Here is my stored procedure in Sql Server:
Create proc getVillageName
#village varchar(50)
as
Begin
SELECT
lookup_table.value FROM dbo.lookup_table INNER JOIN dbo.lookup_description ON
lookup_table.group_id = lookup_description.desc_id WHERE
lookup_description.description = 'Village' AND
lookup_table.value LIKE #village + '%'
End
Here is my code:
Public Function GetVillage(ByVal villageName As String) As List(Of String)
Dim strsql As String
Dim Villagevalue As List(Of String)
Dim param As SqlParameter
Dim conn As New SqlConnection With {.ConnectionString = "Server=MINTOY_DEV\MIGSSERVER;Database=SouthLinkDBO;User=sa;Pwd=123;"}
Dim cmd As New SqlCommand
Dim reader As SqlDataReader
Using conn
strsql = "getVillageName"
cmd = New SqlCommand(strsql, conn)
cmd.CommandType = CommandType.StoredProcedure
param = New SqlParameter("#village", villageName)
cmd.Parameters.Add(param)
conn.Open()
reader = cmd.ExecuteReader
While reader.Read
Villagevalue.Add(reader.Item("value").ToString)
End While
End Using
End Function
You're missing a line:
While reader.Read
Villagevalue.Add(reader.Item("value").ToString)
End While
End Using
Return Villagevalue '<-----------------
End Function
Are you looking at compiler warnings? VB will tell you if you forget a Return statement.
Better yet, open the Project Properties, click on the Compiler tab, and set "Function returning a reference type without a return value" to "Error".
Also, how is this working at all?
Dim Villagevalue As List(Of String)
That should be
Dim Villagevalue As New List(Of String)
Lots of things we can improve here:
Public Iterator Function GetVillage(ByVal villageName As String) As IEnumerable(Of String)
Using conn As New SqlConnection("Server=MINTOY_DEV\MIGSSERVER;Database=SouthLinkDBO;User=sa;Pwd=123;"), _
cmd As New SqlCommand("getVillageName", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#village", SqlDbType.VarChar, 50).Value = villageName
conn.Open()
Using rdr As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
Yield DirectCast(reader("value"), String)
End While
End Using
End Using
End Function
The big thing is we actually return a value (Yield handles this for Iterator functions).
If you really need an actual List(Of String) (Hint: you usually don't; Your code will almost always perform a lot better if you arrange things to work with IEnumerable(Of T) for as long as possible) you can append a .ToList() when calling this method.
everyone, How can I read a cursor from a stored procedure?
This is my code, but it's not working
Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("conexionBD").ToString())
Public Function LoadData() As String
Dim strQuery As String
strQuery = "Kardex_P''"
Using (con)
Dim sqlComm As SqlCommand = New SqlCommand(strQuery, con)
con.Open()
Dim sqlReader As SqlDataReader = sqlComm.ExecuteReader()
If sqlReader.HasRows Then
While (sqlReader.Read())
txtReporte = sqlReader.ToString
End While
End If
End Using
Return txtReporte
End Function
Please I need your help.
Thanks in advance
The cursor code will live in the stored procedure that ultimately returns a set of rows to read. Reference each column by ordinal value or name:
txtReporte.Text = sqlReader(0).ToString()
or
txtReporte.Text = sqlReader("YourColumnName").ToString()
What is wrong in OP code and how to fix it.
Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("conexionBD").ConnectionString
''//.ToString()) wrong but not fatal
Public Function LoadData() As String
Dim txtReporte as String = "" ''//you return this so declare
Dim strQuery As String
strQuery = "Kardex_P" ''//"Kardex_P''" This supposed to be SP name. What '' do inside?
Using (con) ''//this is good
Dim sqlComm As SqlCommand = New SqlCommand(strQuery, con)
''//By default command type is text so next line is critical
sqlComm.CommandType = CommandType.StoredProcedure
con.Open()
Dim sqlReader As SqlDataReader = sqlComm.ExecuteReader()
''//If sqlReader.HasRows Then checking "HasRows is redundant here
While (sqlReader.Read())
''//txtReporte = sqlReader.ToString no comment
txtReporte &= sqlReader("SomeField")
End While
''//End If
con.Close() ''//cleanup recommended
End Using
Return txtReporte
End Function
I hope this will work. Not perfect of course.
The following stored procedure works as I want in the Visual Studio designer. The result is a table containing all the race distances for the input #CourseName
ALTER PROCEDURE [dbo].[getCourseDistancesProc]
#CourseName nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT
RaceDistances.RaceDistance
FROM
RacingMaster
JOIN
RaceDistances ON RacingMaster.Dist_Of_Race_FK = RaceDistances.PKRaceDistancesId
JOIN
Courses ON RacingMaster.RM_Course_FK = Courses.PKCourseId
WHERE
CourseName = #CourseName
END
I want to call the stored procedure from a vb.net application. What data type do I declare as the output variable so that the full result set is returned to the calling app?
There was obviously more work to be done than I had realized, but just in case anyone else stumbles across this question the solution I finally adapted from elsewhere is:-
Dim myConn As SqlConnection
Dim myCmd As SqlCommand
Dim results As String
Dim ConnectionString As String
' Create the connection string.
ConnectionString = "Data Source=*********;" & _
"Initial Catalog=*******;" & _
"Integrated Security=SSPI;"
myConn = New SqlConnection(ConnectionString)
myConn.Open()
Dim InputName As String
InputName = TextBox1.Text
myCmd = New SqlCommand()
myCmd.CommandText = "getCourseDistancesProc"
myCmd.CommandType = CommandType.StoredProcedure
myCmd.Parameters.AddWithValue("#CourseName", Odbc.OdbcType.NVarChar).Value = InputName
myCmd.Connection = myConn
Dim myReader As SqlDataReader = myCmd.ExecuteReader()
If myReader.HasRows Then
Do While myReader.Read()
Dim var As String
var = myReader.GetString(0)
MsgBox(var)
Loop
Else
MsgBox("No rows found.")
End If
myReader.Close()
Obviously, the above is just to demonstrate that the requested data is indeed coming back from the database. But now I know that it is I can handle it in a more useful way.
I am receiving this error:
Procedure or function 'usp__SingleSelectServerRackName' expects parameter '#chvServerName', which was not supplied.
I looked up the error and did not find any applicable solutions.
I was successfully able to run the Proc and retrieve out put information, and was able to successfully retrieve value of cbserver.valuemember in command window.
Any suggestions to correct this problem?
Here is my code:
Imports System.Data.SqlClient
Try
Dim connString As String = "server=ServerName;database=DatabaseName;trusted_connection=yes"
Using connection As New SqlConnection(connString)
'Create the command and set its properties.
Dim SingleSelectServerRackName As SqlCommand = New SqlCommand
SingleSelectServerRackName.Connection = connection
SingleSelectServerRackName.CommandText = "usp__SingleSelectServerRackName"
SingleSelectServerRackName.CommandType = CommandType.StoredProcedure
'Add the input parameter and set its properties
Dim ParamSingleSelectServerName As New SqlParameter()
ParamSingleSelectServerName.ParameterName = "#chvServerName"
ParamSingleSelectServerName.SqlDbType = SqlDbType.VarChar
ParamSingleSelectServerName.Direction = ParameterDirection.Input
ParamSingleSelectServerName.Value = cbServer.SelectedValue.ToString()
Dim ParamSingleSelectServerRackName As New SqlParameter
ParamSingleSelectServerName.ParameterName = "#numServerRackName"
ParamSingleSelectServerRackName.SqlDbType = SqlDbType.VarChar
ParamSingleSelectServerRackName.Direction = ParameterDirection.Output
ParamSingleSelectServerRackName.Size = 50
'Add the parameters to the Parameters collection
SingleSelectServerRackName.Parameters.Add(ParamSingleSelectServerName)
SingleSelectServerRackName.Parameters.Add(ParamSingleSelectServerRackName)
'Open database connection
connection.Open()
'Execute data reader
Dim readerSingleSelectServerRackName As SqlDataReader = SingleSelectServerRackName.ExecuteReader()
readerSingleSelectServerRackName.Close()
cbRackName.ValueMember = SingleSelectServerRackName.Parameters("#numServerRackName").Value.ToString
'Close database connection
connection.Close()
End Using
Catch ex As Exception
MsgBox(ex.Message)
MsgBox(ex.StackTrace)
End Try
Proc:
CREATE Procedure usp__SingleSelectServerRackName
(
#chvServerName AS varchar(50), ---Input variable #chvServerName displays
#numServerRackName AS varchar(50) OUTPUT ---Output variable #numServerRackName
)
AS Begin
IF #chvServerName is null or len(ltrim(#chvServerName)) = 0 ---Check for null value
RAISERROR('Servername cannot be blank.',16,1)
SELECT Rcknm.nm
FROM Rcknm
INNER JOIN Srvr
on srvr.fk_rcknm = Rcknm.ID
WHERE srvr.nm = #chvServerName
End
Looks like you missed something on your copy/paste of parameters.
ParamSingleSelectServerName.ParameterName = "#numServerRackName"
ParamSingleSelectServerName.ParameterName = "#chvServerName"
Your second parameter is overwriting your first. Try this instead.
ParamSingleSelectServerRackName.ParameterName = "#numServerRackName"
Name of the 2nd parameter is same so overwriting it
Look at these two lines
Dim ParamSingleSelectServerRackName As New SqlParameter
ParamSingleSelectServerName.ParameterName = "#numServerRackName"
You are declaring the second parameter, but then you set the name intended for the second parameter to the first parameter.
That's the missing parameter, you have no more a parameter called #chvServerName
You are really making your life difficult. Why not just calling the twos #Rack and #Server ?
I have a simple stored procedure(Select Name,ID from MyTable) and I want to call it from C#(or VB.NET) to populate a dataset.
Here is my code:
Public Class PaymentDataAccess
Public Function GetPaymentData() As DataSet
Dim cn As New SqlClient.SqlConnection
cn.ConnectionString = "Data Source=WORK-HP\BTFSERVER1;Initial Catalog=PaymentReminder;Integrated Security=True"
Dim Cmd As New SqlCommand("GetPaymentData", cn)
Cmd.CommandType = CommandType.StoredProcedure
Dim sa As New SqlDataAdapter(Cmd)
cn.Open()
Dim ds As DataSet = Nothing
Try
sa.Fill(ds)
Catch ex As Exception
Dim i As Integer = 7
End Try
Return ds
End Function
End Class
I am getting an exception at sa.Fill(ds)
{"Value cannot be null.
Parameter name: dataSet"}
System.ArgumentNullException: {"Value cannot be null.
Parameter name: dataSet"}
Here is my stored procedure:
USE [PaymentReminder]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetPaymentData]
AS
BEGIN
SET NOCOUNT ON;
SELECT * from Payments
END
Just change this line from
Dim ds As DataSet = Nothing
to
Dim ds = new DataSet()
You need to pass an initialized DataSet to the SqlDataAdapter.Fill method.
Actually your code is like
sa.Fill(Nothing)
and of course this is not appreciated by the Fill code.