Call SQL function with C# - c#

I write this function in SQL:
ALTER FUNCTION Fn_CheckBill
(
#image AS image,
#number AS nvarchar(50),
#date AS nchar(10)
)
RETURNS bit
AS
BEGIN
DECLARE #flag bit;
IF EXISTS ( SELECT *
FROM tblBill
WHERE ((cast([Image] as varbinary(max)) = cast(#image as varbinary(max))) AND (Number = #number) AND ([Date] = #date)) )
BEGIN
SET #flag = 0
END
ELSE
BEGIN
SET #flag = 1
END
RETURN #flag
END
And write this code in my C# source code:
int flag;
try
{
objCommand = new SqlCommand("SELECT Fn_CheckBill(#image,#date,#number) AS int");
objCommand.CommandType = CommandType.Text;
objCommand.Parameters.AddWithValue("image", image);
objCommand.Parameters.AddWithValue("number", number);
objCommand.Parameters.AddWithValue("date", _Date);
using (objConnection = new SqlConnection(connenctString))
{
objConnection.Open();
objCommand.Connection = objConnection;
flag = int.Parse(objCommand.ExecuteScalar().ToString());
}
if (flag == 1)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
But It throw this exception when executed:
'Fn_CheckBill' is not a recognized function name.
Please help me to solve this problem :(

You need to supply the schema in any SQL function call
objCommand = new SqlCommand("SELECT dbo.Fn_CheckBill(#image,#date,#number) AS int");

I would consider rewriting this as an inline table valued function. Something like this:
create FUNCTION Fn_CheckBill
(
#image AS varbinary(max),
#number AS nvarchar(50),
#date AS nchar(10)
)
RETURNS table
AS
RETURN
SELECT CAST(count(*) as bit) as RowFound
FROM tblBill
WHERE [Image] = #image
AND Number = #number
AND [Date] = #date

Related

Date Format: No overload for method "ToString" takes 1 arguments

I stay with that error when I'm trying to format a date in my code:
Cmd.CommandText = #"
DECLARE #command varchar(5000);
DECLARE #RestoreList TABLE(DB_name VARCHAR(100), RS_name VARCHAR(100), RS_DateFinExercice DATE, RS_IsClosed VARCHAR(50));
SELECT #command = 'IF ''?'' IN (SELECT name FROM sys.databases WHERE HAS_DBACCESS(name) = 1 AND CASE WHEN state_desc = ''ONLINE'' THEN OBJECT_ID( QUOTENAME( name ) + ''.[dbo].[P_DOSSIER]'',''U'' ) END IS NOT NULL) BEGIN USE [?] SELECT DB_name = CAST(DB_NAME() AS VARCHAR(100)), RS_name = CAST(a.D_RaisonSoc AS VARCHAR(100)), RS_DateFinExercice = CAST((SELECT Max(v) FROM (VALUES (a.[D_FinExo01]), (a.[D_FinExo02]), (a.[D_FinExo03]),(a.[D_FinExo04]),(a.[D_FinExo05])) AS value(v)) AS DATE), RS_IsClosed = CAST((SELECT CASE WHEN (SUM (CASE WHEN JM_Cloture !=2 THEN 1 ELSE 0 END)>0) THEN '''' ELSE ''arc'' END FROM F_JMOUV) AS VARCHAR(50)) FROM [dbo].[P_DOSSIER] a INNER JOIN F_JMOUV b ON DB_name() = DB_NAME() GROUP BY D_RaisonSoc, D_FinExo01, D_FinExo02, D_FinExo03, D_FinExo04, D_FinExo05 HAVING COUNT(*) > 1 END'
INSERT INTO #RestoreList EXEC sp_MSforeachdb #command;
SELECT * FROM #RestoreList ORDER BY DB_name;";
SqlDataReader dr = Cmd.ExecuteReader();
List<DBtoRestore> dgUIDcollection = new List<DBtoRestore>();
if (dr.HasRows)
{
while (dr.Read())
{
DBtoRestore currentdgUID = new DBtoRestore
{
CUID_dbname = dr["DB_name"].ToString(),
CUID_RaisonSoc = dr["RS_name"].ToString(),
CUID_DateFinExercice = dr["RS_DateFinExercice"].ToString(),
CUID_IsClosed = dr["RS_IsClosed"].ToString()
};
dgUIDcollection.Add(currentdgUID);
}
}
dgDBtoRestore.ItemsSource = dgUIDcollection;
Cnx.Close();
The problem is on this line of code:
CUID_DateFinExercice = dr["RS_DateFinExercice"].ToString()
For now, my datagrid report date like 01/01/2020 00:00:00. In SQL, I have 01-01-2020 style.
I want to have the same style in my datagrid.
I have try something like ToString("dd-MM-yyyy") but it's in that context I've received the error.
Any idea to help me?
Convert to a DateTime and then call ToString on it:
Convert.ToDateTime(dr["RS_DateFinExercice"]).ToString("dd-MM-yyyy")
Solution :
CUID_DateFinExercice = ((DateTime)dr["RS_DateFinExercice"]).ToString("dd-MM-yyyy"),

Getting weird value in C#

Getting exactly correct data in stored procedure. but when i am trying to get that value in C# datatable getting wrong data. not sure why i am getting that.
Here is my stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetSurveyStatistic]
(#SurveyID int,
#NameOfSubmitter varchar(200),
#NameOfPrivacyContact varchar(200),
#HspOrganizationalName varchar(200),
#HspSiteNumber varchar(200),
#FromDate datetime,
#ToDate datetime,
#weekly bit)
AS
BEGIN
IF (#ToDate IS NOT NULL)
SET #ToDate = DATEADD(DAY, 1, #ToDate)
IF #Weekly = 0
BEGIN
SELECT
CAST(CAST(StartedDateTime AS date) AS varchar(10)) Value,
COUNT(*) cnt
FROM
SubmittedSurveys
WHERE
(SurveyID = #SurveyID OR #SurveyID IS NULL)
AND (StartedDateTime >= #FromDate OR #FromDate IS NULL)
AND (StartedDateTime <= #ToDate OR #ToDate IS NULL)
AND (LOWER(ProvidedNameOfSubmitter) LIKE LOWER(#NameOfSubmitter) + '%'
OR #NameOfSubmitter IS NULL OR #NameOfSubmitter = '')
AND (LOWER(NameOfPrivacyContact) LIKE LOWER(#NameOfPrivacyContact) + '%'
OR #NameOfPrivacyContact IS NULL
OR #NameOfPrivacyContact = '')
AND (LOWER(HspOrganizationalName) LIKE LOWER(#HspOrganizationalName) + '%'
OR #HspOrganizationalName IS NULL
OR #HspOrganizationalName = '')
AND (LOWER(HspSiteNumber) LIKE LOWER(#HspSiteNumber)
OR #HspSiteNumber IS NULL OR #HspSiteNumber = '')
GROUP BY
CAST(StartedDateTime AS date)
ORDER BY
1
END
ELSE BEGIN
SELECT
CAST(DATEPART(WEEK, StartedDateTime) AS varchar(10)) Value,
COUNT(*) cnt
FROM
SubmittedSurveys
WHERE
(SurveyID = #SurveyID OR #SurveyID IS NULL)
AND (StartedDateTime >= #FromDate OR #FromDate IS NULL)
AND (StartedDateTime <= #ToDate OR #ToDate IS NULL)
AND (LOWER(ProvidedNameOfSubmitter) LIKE LOWER(#NameOfSubmitter) + '%'
OR #NameOfSubmitter IS NULL OR #NameOfSubmitter = '')
AND (LOWER(NameOfPrivacyContact) LIKE LOWER(#NameOfPrivacyContact) + '%'
OR #NameOfPrivacyContact IS NULL
OR #NameOfPrivacyContact = '')
AND (LOWER(HspOrganizationalName) LIKE LOWER(#HspOrganizationalName) + '%'
OR #HspOrganizationalName IS NULL
OR #HspOrganizationalName = '')
AND (LOWER(HspSiteNumber) LIKE LOWER(#HspSiteNumber)
OR #HspSiteNumber IS NULL OR #HspSiteNumber = '')
GROUP BY
CAST(DATEPART(WEEK, StartedDateTime) AS varchar(10))
ORDER BY
1
END
END
and here is the results
but in front end getting "Value" ="Date" instead of week value
Here is the code of front end
public static List<SubmittedSurveys> GetSurveyStatistic(int SubmittedSurveyId, DateTime
StartedDateTime, string NameOfSubmitter, string NameOfPrivacyContact, string
HspOrganizationalName, string HspSiteNumber,
DateTime CompletedDateTime,bool weekly)
{
try
{
DatabaseProviderFactory factory = new DatabaseProviderFactory();
Database _wohcDB = factory.Create("SurveyToolDBEntities");
// SqlDatabase _wohcDB = DatabaseFactory.CreateDatabase("SurveyToolDBEntities") as
SqlDatabase;
string sqlCommand = "[GetSurveyStatistic]";
DbCommand dbCommand = _wohcDB.GetStoredProcCommand(sqlCommand);
_wohcDB.AddInParameter(dbCommand, "#SurveyID", DbType.Int32, SubmittedSurveyId);
_wohcDB.AddInParameter(dbCommand, "#FromDate", DbType.DateTime, StartedDateTime);
_wohcDB.AddInParameter(dbCommand, "#ToDate", DbType.DateTime, CompletedDateTime);
_wohcDB.AddInParameter(dbCommand, "#NameOfSubmitter", DbType.String, NameOfSubmitter);
_wohcDB.AddInParameter(dbCommand, "#NameOfPrivacyContact", DbType.String, NameOfPrivacyContact);
_wohcDB.AddInParameter(dbCommand, "#HspOrganizationalName", DbType.String, HspOrganizationalName);
_wohcDB.AddInParameter(dbCommand, "#HspSiteNumber", DbType.String, HspSiteNumber);
_wohcDB.AddInParameter(dbCommand, "#weekly", DbType.String, weekly);
DataSet ds = _wohcDB.ExecuteDataSet(dbCommand);
_submittedSurvey = ReportsController.DbConverter.DataTable2List<SubmittedSurveys>(ds.Tables[0]);
//_submittedSurvey[0].SurveyReports = ReportsController.DbConverter.DataTable2List<Reports>(ds.Tables[1]);
}
catch (Exception ex)
{
string message = ex.Message.ToString();
}
return _submittedSurvey;
}
Here is the screenshot of front end where I am getting wrong value as a date instead of week
Can somebody help me to resolve this issue. This is so weird. i also tried to cast in int but getting error that date can not convert into int. I am not sure that why I am getting wrong data in front end and getting right data in backend?
Please help me.
Try to Change:
_wohcDB.AddInParameter(dbCommand, "#weekly", DbType.String, weekly);
To:
_wohcDB.AddInParameter(dbCommand, "#weekly", DbType.Boolean, weekly);
Just run the else part then it will work fine. with this query it will always go to if statement because of #Weekly =0.

How to pass int parameter to DATASET implemented interface method in C#

Below are the quick read about my code implemented
Declared interface in ILogic.cs file.
DataSet updateStatus();
Return interface in CLogic.cs file.
public DataSet updateStatus()
{
return this.Repository.updateStatus();
}
Interface method implementation in Repository.cs file, What is the correct way to implement this method.
public DataSet updateStatus()
{
try
{
dataSet = new DataSet();
using (SqlCommand cmd = new SqlCommand(StoredProcedures.JobStausUpdate, conETLITG))
{
conITG.Open();
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
adapt.SelectCommand.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(jobid);
adapt.Fill(dataSet);
conITG.Close();
}
return dataSet;
}
catch (Exception es)
{
throw es;
}
}
Calling method as below in Program.cs file so how can I pass #Execution_Job_ID in updateStatus
intjobId=86746;
commonLogic.updateStatus(jobId);
SQL Store Procedure
CREATE PROCEDURE JobStausUpdate
( #Execution_Job_ID INT
)
AS
BEGIN
SELECT TOP 3
ji.jobname,
jel.*
INTO #tempjobstatus
FROM joblog jel
INNER JOIN jobinfo ji
ON jel.jobid=ji.jobid
WHERE jel.jobid IN (67,89,44)
AND jel.joblogid <= #Execution_Job_ID
ORDER BY 2 DESC
DECLARE #ARefresh VARCHAR(30),
#BRefresh VARCHAR(30),
#statusId INT,
#statusReturn INT
SET #ARefresh =
(
SELECT jobstatus
FROM #tempjobstatus
WHERE jobname ='aRefresh')
IF (#ARefresh = 'Failed')
BEGIN
SET #BRefresh =
(
SELECT jobstatus
FROM #tempjobstatus
WHERE jobname ='bRefresh')
IF (#BRefresh = 'In Progress')
BEGIN
SET #statusId =
(
SELECT joblogid
FROM #tempjobstatus
WHERE jobname ='bRefresh')
UPDATE joblog
SET jobstatus = 'Failed'
WHERE joblogid = #statusId
SET #statusReturn=1
END
ELSE SET #statusReturn =0
END
ELSE IF (#ARefresh = 'Completed')
BEGIN
SET #BRefresh =
(
SELECT jobstatus
FROM #tempjobstatus
WHERE jobname ='bRefresh')
IF (#BRefresh = 'In Progress')
BEGIN
SET #statusId =
(
SELECT joblogid
FROM #tempjobstatus
WHERE jobname ='bRefresh')
UPDATE joblog
SET jobstatus = 'Completed'
WHERE joblogid = #statusId
SET #statusReturn=1
END
ELSE SET #statusReturn =0
END
ELSE
BEGIN
SET #statusReturn=0
END
SELECT #statusReturn
SELECT * FROM #tempjobstatus
END
Maybe I'm misunderstanding the question but you just need to update your Interface to include the int you want to pass then change your cmc.Parameters.Add.
DataSet updateStatus(int jobid);
cmd.Parameters.Add(new SqlParameter("#JobID",jobid));

Must declare the scalar variable "#ManagerID"

I have a Running Time Error:
Must declare the scalar variable \"#ManagerID
I'm Sure I Have Declare All Variables In My CLass And My Procudure
My Class Code:
public DataTable Select(int ID,string NameFa, string Address, int ManagerID, short TotalUnits, int ChargeMethodID)
{
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("NameFa", typeof(string));
table.Columns.Add("Address", typeof(string));
table.Columns.Add("ManagerID", typeof(int));
table.Columns.Add("TotalUnits", typeof(short));
table.Columns.Add("ChargeMethodID", typeof(int));
try
{
con.Open();
SqlCommand command = new SqlCommand("dbo.SelectBuilding", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#ID", ID));
command.Parameters.Add(new SqlParameter("#NameFa", NameFa));
command.Parameters.Add(new SqlParameter("#Address", Address));
command.Parameters.Add(new SqlParameter("#ManagerID", ManagerID));
command.Parameters.Add(new SqlParameter("#TotalUnits", TotalUnits));
command.Parameters.Add(new SqlParameter("#ChargeMethodID", ChargeMethodID));
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(table);
return table;
}
And My Procudure Code Is:
#ID int,
#NameFa nvarchar(150),
#Address nvarchar(MAX),
#ManagerID int,
#TotalUnits smallint,
#ChargeMethodID int
As
Begin
IF(#ID >0 )
Begin
Select ID,NameFa,Address,ManagerID,TotalUnits,ChargeMethodID From Buildings where ID = #ID
End
ELSE
Begin
Declare #sqlTxt nvarchar(MAX)
SET #sqlTxt = 'SELECT ID,NameFa,Address,ManagerID,TotalUnits,ChargeMethodID FROM Buildings where ID>0'
IF(#NameFa!= null)
BEGIN
SET #sqlTxt = #sqlTxt + ' AND NameFa Like ''%#NameFa%'''
END
IF(#Address!= null)
BEGIN
SET #sqlTxt = #sqlTxt + ' AND Address Like ''%#Address%'''
END
IF(#ManagerID > 0)
BEGIN
SET #sqlTxt = #sqlTxt + ' AND ManagerID = #ManagerID'
END
IF(#TotalUnits > 0)
BEGIN
SET #sqlTxt = #sqlTxt + ' AND TotalUnits = #TotalUnits'
END
IF(#ChargeMethodID > 0)
BEGIN
SET #sqlTxt = #sqlTxt + ' AND ChargeMethodID = #ChargeMethodID'
END
EXEC (#sqlTxt);
End
END
And I want to use Select Function:
DataTable dt = new DataTable();
Buildings.Building bb = new Buildings.Building() {ID=0,NameFa="",Address="",ManagerID=OwnerID,TotalUnits=0,ChargeMethodID=0 };
dt = bu.Select(bb.ID,bb.NameFa,bb.Address,bb.ManagerID,bb.TotalUnits,bb.ChargeMethodID);
You are not passing the parameters to the exec statement. I would change it to sp_executesql which has an optional argument with parameters.
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql
Edit: I strongly suggest getting rid of the exec and/or sp_executesql commands. Because depending on the input you could:
a) Get runtime errors due to user typing SQL string delimiters as a valid input. Example O'Hara as a surname.
b) A malicious user could mess badly with your database.
You could get similar result in a more simple way:
Select
ID,NameFa,Address,ManagerID,TotalUnits,ChargeMethodID
From
Buildings
where
(#Id = 0 or ID = #Id)
and (#NameFa = '' or NameFa = #NameFa)
and (#ManagerID = 0 or ManagerID = #ManagerID)
// repeat for the rest of the optional search conditions

Failed to get result of stored procedure

I created a procedure that returns the ID of the Question based on the input text
ALTER PROCEDURE [dbo].[GetQuestionIDbyTekst]
(
#Tekst nvarchar(100)
)
AS
DECLARE #QuestionID int
SELECT QuestionID
FROM dbo.Questions
WHERE Tekst = #Tekst
RETURN #QuestionID
and I have a problem in getting the value of the QuestionID:
public static int getQuestionID(Question p)
{
using (Entities dm = new Entities())
{
return dm.GetQuestionIDbyTekst(p.Tekst);
}
}
Make the #QuestionID as Output parameter. Also you need to assign the result to #QuestionID
ALTER PROCEDURE [dbo].[GetQuestionIDbyTekst]
(
#Tekst nvarchar(100),
#QuestionID INT OUTPUT
)
AS
BEGIN
DECLARE #QuestionID int
SELECT #QuestionID = QuestionID FROM dbo.Questions WHERE Tekst = #Tekst
END
please try this:
ALTER PROCEDURE [dbo].[GetQuestionIDbyTekst]
(
#Tekst nvarchar(100)
)
AS
-- DECLARE #QuestionID int
SELECT QuestionID
FROM dbo.Questions
WHERE Tekst = #Tekst
-- RETURN #QuestionID
You can use your variant of the stored procedure.
And if you use ADO.NET and want to get return value, try this:
SqlConnection con = new SqlConnection(#"Data Source=localhost\***;Initial Catalog=***;Integrated Security=True;Persist Security Info=False;");
con.Open();
SqlCommand cmd = new SqlCommand("GetQuestionIDbyTekst", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#Tekst", System.Data.SqlDbType.NVarChar).Value = "eee";
SqlParameter returnPar = new SqlParameter();
returnPar.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(retturnPar);
cmd.ExecuteScalar();
var result = returnPar.Value;
If you use Entity Framework, you may use this variant:
public static int GetQuestionIDbyTekst(string question)
{
using (var context = new EfDbContext())
{
var test = new SqlParameter("#Tekst", question);
var resultParam = new SqlParameter("#result", SqlDbType.Int);
resultParam.Direction = ParameterDirection.Output;
context.Database.ExecuteSqlCommand("exec #result = [dbo].[testProc] #Tekst", resultParam, test);
return (int)resultParam.Value;
}
}

Categories