Stored Procedure Not Accepting Integer Parameter - c#

I have been using a Stored Procedure created by our DB guy, who happens to be out of town for the next week. The SP used to work, but before he left, the DB guy edited the SP, causing my code to throw a server error: "Column name or number of supplied values does not match table definition". He claimed before he left the SP should mainly be the same, so I'm at a loss for why it's no longer matching.
Here is the c# code:
System.Data.SqlClient.SqlCommand objCmd = new
System.Data.SqlClient.SqlCommand("dci.webDonorStatistics", objConn);
objCmd.CommandTimeout = 950;
objCmd.CommandType = System.Data.CommandType.StoredProcedure;
objCmd.Parameters.Add(new
System.Data.SqlClient.SqlParameter("#FiscalYear", 2018));
GridView1.DataSource = objCmd.ExecuteReader();
GridView1.DataBind();
Here is the declaration of the SP:
ALTER PROCEDURE [dci].[webDonorStatistics] #FiscalYear INT
AS
BEGIN
--DECLARE #FiscalYear INT = 2018
DECLARE
#StartDate DATE = CONVERT(DATE, '01-OCT-' + CONVERT(CHAR(4), #FiscalYear - 1))
, #EndDate DATE = DATEADD(DAY, -1, GETDATE())
IF #EndDate >= CONVERT(DATE, '30-SEP-' + CONVERT(CHAR(4), #FiscalYear))
SELECT #EndDate = CONVERT(DATE, '30-SEP-' + CONVERT(CHAR(4), #FiscalYear))
ELSE
SELECT #EndDate = DATEADD(DAY, -1, CONVERT(DATE, '01-' + DATENAME(MONTH, GETDATE()) + '-' + CONVERT(CHAR(4), YEAR(GETDATE())))) -- End of previous month
IF DATEDIFF(DAY, #StartDate, #EndDate) < 0
SELECT #EndDate = GETDATE()
BEGIN TRY
DROP TABLE #webDonorStatistics
END TRY
BEGIN CATCH
END CATCH
Any help would be greatly appreciated. Thanks in advance.

First step is to isolate your error. Is your error thrown from your application code or database code?
If you follow 3Dave's suggestion, what do you get? Assuming you are pointed to the correct database server. Try running:
EXEC [dci].[webDonorStatistics] 2018
If the above call does not return any error, I would check the application code.

Your Error indicates that the data which you are trying to insert into the table is not valid, You would have to right-click on the stored procedure and click on execute stored procedure where you can insert the parameter for the fiscal year, The execution should fail. Then create a copy of same stored procedure with a different name and change the data type for the fiscal year and see if that would fix the issue and give you the result when you execute the stored procedure. Also on the Stored Proc could which you have I dont see any insert commands if there are any try checking the data type of what you are trying to insert and the data type of what is present inside the table schema if that doesn't match then you can change accordingly .

Related

System.Data.SqlClient.SqlException: 'Procedure or function sp_friend has too many arguments specified.' [duplicate]

I am developing my very first stored procedure in SQL Server 2008 and need advice concerning the errors message.
Procedure or function xxx too many arguments specified
which I get after executing the stored procedure [dbo].[M_UPDATES] that calls another stored procedure called etl_M_Update_Promo.
When calling [dbo].[M_UPDATES] (code see below) via right-mouse-click and ‘Execute stored procedure’ the query that appears in the query-window is:
USE [Database_Test]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[M_UPDATES]
SELECT 'Return Value' = #return_value
GO
The output is
Msg 8144, Level 16, State 2, Procedure etl_M_Update_Promo, Line 0
Procedure or function etl_M_Update_Promo has too many arguments specified.
QUESTION: What does this error message exactly mean, i.e. where are too many arguments? How to identify them?
I found several threads asking about this error message, but the codes provided were all different to mine (if not in another language like C# anyway). So none of the answers solved the problem of my SQL query (i.e. SPs).
Note: below I provide the code used for the two SPs, but I changed the database names, table names and column names. So, please, don’t be concerned about naming conventions, these are only example names!
(1) Code for SP1 [dbo].[M_UPDATES]
USE [Database_Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ M_UPDATES] AS
declare #GenID bigint
declare #Description nvarchar(50)
Set #GenID = SCOPE_IDENTITY()
Set #Description = 'M Update'
BEGIN
EXEC etl.etl_M_Update_Promo #GenID, #Description
END
GO
(2) Code for SP2 [etl_M_Update_Promo]
USE [Database_Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [etl].[etl_M_Update_Promo]
#GenId bigint = 0
as
declare #start datetime = getdate ()
declare #Process varchar (100) = 'Update_Promo'
declare #SummeryOfTable TABLE (Change varchar (20))
declare #Description nvarchar(50)
declare #ErrorNo int
, #ErrorMsg varchar (max)
declare #Inserts int = 0
, #Updates int = 0
, #Deleted int = 0
, #OwnGenId bit = 0
begin try
if #GenId = 0 begin
INSERT INTO Logging.dbo.ETL_Gen (Starttime)
VALUES (#start)
SET #GenId = SCOPE_IDENTITY()
SET #OwnGenId = 1
end
MERGE [Database_Test].[dbo].[Promo] AS TARGET
USING OPENQUERY( M ,'select * from m.PROMO' ) AS SOURCE
ON (TARGET.[E] = SOURCE.[E])
WHEN MATCHED AND TARGET.[A] <> SOURCE.[A]
OR TARGET.[B] <> SOURCE.[B]
OR TARGET.[C] <> SOURCE.[C]
THEN
UPDATE SET TARGET.[A] = SOURCE.[A]
,TARGET.[B] = SOURCE.[B]
, TARGET.[C] = SOURCE.[c]
WHEN NOT MATCHED BY TARGET THEN
INSERT ([E]
,[A]
,[B]
,[C]
,[D]
,[F]
,[G]
,[H]
,[I]
,[J]
,[K]
,[L]
)
VALUES (SOURCE.[E]
,SOURCE.[A]
,SOURCE.[B]
,SOURCE.[C]
,SOURCE.[D]
,SOURCE.[F]
,SOURCE.[G]
,SOURCE.[H]
,SOURCE.[I]
,SOURCE.[J]
,SOURCE.[K]
,SOURCE.[L]
)
OUTPUT $ACTION INTO #SummeryOfTable;
with cte as (
SELECT
Change,
COUNT(*) AS CountPerChange
FROM #SummeryOfTable
GROUP BY Change
)
SELECT
#Inserts =
CASE Change
WHEN 'INSERT' THEN CountPerChange ELSE #Inserts
END,
#Updates =
CASE Change
WHEN 'UPDATE' THEN CountPerChange ELSE #Updates
END,
#Deleted =
CASE Change
WHEN 'DELETE' THEN CountPerChange ELSE #Deleted
END
FROM cte
INSERT INTO Logging.dbo.ETL_log (GenID, Startdate, Enddate, Process, Message, Inserts, Updates, Deleted,Description)
VALUES (#GenId, #start, GETDATE(), #Process, 'ETL succeded', #Inserts, #Updates, #Deleted,#Description)
if #OwnGenId = 1
UPDATE Logging.dbo.ETL_Gen
SET Endtime = GETDATE()
WHERE ID = #GenId
end try
begin catch
SET #ErrorNo = ERROR_NUMBER()
SET #ErrorMsg = ERROR_MESSAGE()
INSERT INTO Logging.dbo.ETL_Log (GenId, Startdate, Enddate, Process, Message, ErrorNo, Description)
VALUES (#GenId, #start, GETDATE(), #Process, #ErrorMsg, #ErrorNo,#Description)
end catch
GO
You invoke the function with 2 parameters (#GenId and #Description):
EXEC etl.etl_M_Update_Promo #GenID, #Description
However you have declared the function to take 1 argument:
ALTER PROCEDURE [etl].[etl_M_Update_Promo]
#GenId bigint = 0
SQL Server is telling you that [etl_M_Update_Promo] only takes 1 parameter (#GenId)
You can alter the procedure to take two parameters by specifying #Description.
ALTER PROCEDURE [etl].[etl_M_Update_Promo]
#GenId bigint = 0,
#Description NVARCHAR(50)
AS
.... Rest of your code.
Use the following command before defining them:
cmd.Parameters.Clear()
This answer is based on the title and not the specific case in the original post.
I had an insert procedure that kept throwing this annoying error, and even though the error says, "procedure....has too many arguments specified," the fact is that the procedure did NOT have enough arguments.
The table had an incremental id column, and since it is incremental, I did not bother to add it as a variable/argument to the proc, but it turned out that it is needed, so I added it as #Id and viola like they say...it works.
For those who might have the same problem as me, I got this error when the DB I was using was actually master, and not the DB I should have been using.
Just put use [DBName] on the top of your script, or manually change the DB in use in the SQL Server Management Studio GUI.
Yet another cause of this error is when you are calling the stored procedure from code, and the parameter type in code does not match the type on the stored procedure.
I feel ashamed for even having to post this, but it might help someone in the future. Make sure you don't have a typo in your function call!
I kept getting this error trying to call a function and couldn't figure out why. My function and call had the same number of arguments (or so I thought).
Here's my function call:
SELECT FORMAT_NAME(A.LASTNAME, A.FIRSTNAME, A,MIDDLENAME)
It's easier to see in Stack Overflow, but it wasn't so obvious in SSMS that I had a comma in place of a period for A.MIDDLENAME.
SELECT FORMAT_NAME(A.LASTNAME, A.FIRSTNAME, A.MIDDLENAME)
Simple user error.
In addition to all the answers provided so far, another reason for causing this exception can happen when you are saving data from list to database using ADO.Net.
Many developers will mistakenly use for loop or foreach and leave the SqlCommand to execute outside the loop, to avoid that make sure that you have like this code sample for example:
public static void Save(List<myClass> listMyClass)
{
using (var Scope = new System.Transactions.TransactionScope())
{
if (listMyClass.Count > 0)
{
for (int i = 0; i < listMyClass.Count; i++)
{
SqlCommand cmd = new SqlCommand("dbo.SP_SaveChanges", myConnection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#ID", listMyClass[i].ID);
cmd.Parameters.AddWithValue("#FirstName", listMyClass[i].FirstName);
cmd.Parameters.AddWithValue("#LastName", listMyClass[i].LastName);
try
{
myConnection.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException sqe)
{
throw new Exception(sqe.Message);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
myConnection.Close();
}
}
}
else
{
throw new Exception("List is empty");
}
Scope.Complete();
}
}
You either have to double check the Parameters on both side (StoredProcedure And Code):
Make Sure they are the same on both ends regarding to the number of them.
Make Sure you have NOT changed your StoredProcedure code and forgot to Execute it, nothing bad happens if you hit F5 to make sure have all the changes committed and saved.
Make Sure you you have the same naming convention on both sides (Not Likely to be the cause but it worth a shot).

How to update existing rows via trigger with C# in SQL

I have a table in SQL called EmpLog which contains the 'start' and 'end' data for employees. I'm quite confused as to how I'm going to change the variables within the trigger during update since it has to cater to all different employees. Do I need to alter the trigger via sql parameter in c# for every insertion? or is there an alternative to keep it minimal and efficient? Thank you in advance. Since as far as I'm able to understand triggers are hard coded onto the database, which is changeable through 'ALTER'. What can I do to change existing row's with different IDs via trigger?
create trigger TrgEmpLog on EmpLog
AFTER UPDATE
AS
declare #shiftstart time;
declare #shiftend time;
declare #totalminutes decimal(18,2);
IF EXISTS (SELECT shiftend FROM EmpLog WHERE EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and shiftend is not null)
BEGIN
IF EXISTS (SELECT EmpLog.TotalMinutes from EmpLog WHERE EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and TotalMinutes is not null)
BEGIN
ROLLBACK TRANSACTION
END
ELSE
select #shiftstart=EmpLog.ShiftStart from EmpLog where EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and TotalMinutes IS NULL;
select #shiftend=EmpLog.ShiftEnd from EmpLog where EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and TotalMinutes IS NULL;
select #totalminutes=DATEDIFF(MINUTE,#shiftstart, #shiftend);
UPDATE EmpLog
SET TotalMinutes=#totalminutes/60.00
WHERE EmpID= "C# Variable"and CONVERT(date,LogDate) = CONVERT(date, GETDATE());
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
And the code that I'm using to prompt the trigger is:
UPDATE EmpLog
SET ShiftEnd = 'current time'
WHERE EmpID='C# variable' and CONVERT(date,LogDate) = CONVERT(date, GETDATE());
This code below ends in a trigger, but it works when I remove the 'and logDate = getdate().
UPDATE EmpLog SET ShiftEnd = '09:00:00' WHERE EmpID = 1 and CONVERT(date, LogDate) = CONVERT(date, GETDATE())
This code below worked for me with some quick testing. Maybe it will work for what you need. The actual trigger part is probably all you really need, the rest I was using to test.
The way this is written, it will only update the current, and relevant record (the one being updated at the time). Joining to the inserted table makes sure that happens. Use the inserted and deleted Tables (MSDN)
CREATE TABLE EmpLog (EmpID int, ShiftStart time, Shiftend time, LogDate date, TotalMinutes decimal(18,2));
GO
-- Trigger starts here
CREATE TRIGGER TrgEmpLog ON EmpLog
AFTER UPDATE
AS
IF EXISTS (SELECT *
FROM EmpLog A JOIN inserted B
ON A.EmpID = B.EmpID
WHERE CONVERT(date, A.LogDate) = CONVERT(date, GETDATE())
AND A.shiftend IS NOT NULL)
BEGIN
IF EXISTS (SELECT *
FROM EmpLog A JOIN inserted B
ON A.EmpID = B.EmpID
WHERE CONVERT(date, A.LogDate) = CONVERT(date, GETDATE())
AND A.TotalMinutes IS NOT NULL)
BEGIN
ROLLBACK TRANSACTION
END
UPDATE EmpLog
SET TotalMinutes=DATEDIFF(MINUTE, A.ShiftStart, A.Shiftend)/60.00
FROM EmpLog A JOIN inserted B
ON A.EmpID = B.EmpID;
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
GO
-- Trigger End here
INSERT INTO EmpLog (EmpID, ShiftStart, Shiftend, LogDate) VALUES (1, '00:00:00', NULL, GETDATE()),
(2, '08:00:00', NULL, GETDATE()),
(3, '16:00:00', NULL, GETDATE());
SELECT * FROM EmpLog;
UPDATE EmpLog SET Shiftend = '08:00:00' WHERE EmpID = 1;
SELECT * FROM EmpLog;
DROP TABLE EmpLog;
You may have to play around with some of the IF EXISTS, if they don't follow you logic exactly.
As #massimiliano mentioned in the comments, triggers can get quite complicated if you want them to. For me, I avoid that. The trigger is always one of the last places I think to look when troubleshooting issues. Personal preference!
Good Luck!

How can I get a date from SQL Server into Oracle 12c? Dates are being inverted (backwards)

I'm having a real problem getting a date from SQL Server into Oracle while maintaining the correct value.
The value in SQL Server looks like: "Apr 28 1969 12:00AM"
When I pull this value into a .NET DateTime it looks like: "04/28/1969 12:00AM"
When it gets inserted into Oracle it looks like: "28-APR-19"
The Oracle date looks correct at quick glance, but if I do a TO_CHAR(DATE, 'MM/DD/YYYY') I get "04/28/6919" <---- The year is backwards!!
Here's a set of dates from Oracle:
01/18/5919
09/19/8819
02/13/5619
08/30/5819
04/28/6519
08/22/6919
10/24/6119
02/27/6919
02/28/6019
12/20/6219
09/28/3619
10/02/6219
All years end in '19' because they are all backwards!
Because Oracle thinks every one of my years ends with "19" it thinks all leap years are invalid and I have a large set of data I can't even get inserted (not to mention the bad dates)
I'm using a simple stored proc to get the data out of SQL Server, the data is then stored in a simple POCO. I'm using Oracle.DataAccess.OracleBulkCopy to do my actual insert using the DataTable. I have no control over how I retrieve the data or how I save it... but I can manipulate it in between.
So far I've tried returning the date as a string and doing formatting on it (dd-MMM-yyyy) and (yyyymmdd) - neither worked. I've also tried setting the date to null if it was a leap year and trying to set it directly afterwards... it's a hack, but that didn't do any good either.
Any help is appreciated.
My stored proc:
USE [InsuranceFileProcessing]
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[P_GET_INSURANCE_POLICY_HOLDERS_FOR_DATA_UPLOAD]
#INSURANCE_COMPANY_CODE VARCHAR(5)
, #INSURANCE_FILE_UPLOAD_LOG_ID INT
, #START_ROW_NUM INT
, #END_ROW_NUM INT
, #GET_LEAP_YEARS BIT
AS
BEGIN
DECLARE #ERROR_NUMBER INT
DECLARE #ERROR_SEVERITY INT
DECLARE #ERROR_STATE INT
DECLARE #ERROR_PROCEDURE NVARCHAR(100)
DECLARE #ERROR_LINE INT
DECLARE #ERROR_MESSAGE NVARCHAR(4000)
SET NOCOUNT ON
BEGIN
BEGIN TRY
SELECT DISTINCT
IT.INSURANCE_COMPANY_CODE INS_COMPANY_NUM
, IP.POLICY_NUMBER INS_POLICY_NUM
, PH.FIRST_NAME PH_FIRST_NAME
, PH.MIDDLE_NAME PH_MIDDLE_NAME
, PH.LAST_NAME PH_LAST_NAME
, LEFT(PH.NAME_SUFFIX,1) PH_NAME_SUFFIX
, PH.ADDRESS PH_ADDRESS
, PH.CITY PH_CITY
, PH.STATE PH_STATE
, PH.ZIPCODE PH_ZIP_CODE
, CONVERT(VARCHAR, PH.DOB, 100) PH_DATE_OF_BIRTH
, PH.GENDER PH_GENDER
, PH.FL_DLN INS_DL_NUMBER
, PH.FED_TIN INS_FEID
, PH.FL_DLN_CROSS_REF FL_DLN_CROSS_REF
, PH.FL_DLN_GENERATED FL_DLN_GENERATED
, PH.NON_STRUCTURED_NAME PH_NON_STRUCT_NAME
, PH.EFFECTIVE_DATE EFFECTIVE_DATE
, ( CASE PH.COMPANY_INDICATOR
WHEN 'Y' THEN 'F'
WHEN 'N' THEN 'T'
ELSE 'T'
END ) PERSONAL_FLAG
--, CONVERT(VARCHAR(12),IP.UPDATE_TS,110) INSERT_TIMESTAMP
, IP.CREATED_TS INSERT_TIMESTAMP
, IDENTITY(INT,1,1) AS ROWNUM
, ph.CUSTOMER_NUMBER CUSTOMER_NUMBER
INTO
#UPLOAD_POLICY_HOLDER
FROM INSURANCE_TRANSACTION IT
INNER JOIN INSURANCE_COMPANIES IC ON IC.INSURANCE_COMPANY_ID = IT.INSURANCE_COMPANY_ID
INNER JOIN INSURANCE_POLICY IP ON IT.INSURANCE_POLICY_ID = IP.INSURANCE_POLICY_ID
INNER JOIN POLICY_HOLDER PH ON IP.INSURANCE_POLICY_ID = PH.INSURANCE_POLICY_ID
WHERE IT.INSURANCE_COMPANY_CODE = #INSURANCE_COMPANY_CODE
AND IT.INSURANCE_FILE_UPLOAD_LOG_ID = #INSURANCE_FILE_UPLOAD_LOG_ID
AND IT.HAS_ERROR = 0
AND PH.HAS_ERROR = 0
AND ((LEFT(REPLACE(CONVERT(VARCHAR(10), DOB, 101), '/', ''), 4) = '0229' AND #GET_LEAP_YEARS = 1)
OR (LEFT(REPLACE(CONVERT(VARCHAR(10), DOB, 101), '/', ''), 4) <> '0229' AND #GET_LEAP_YEARS = 0))
ORDER BY IT.INSURANCE_COMPANY_CODE , IP.POLICY_NUMBER ;
SELECT * FROM #UPLOAD_POLICY_HOLDER
WHERE ROWNUM > #START_ROW_NUM AND ROWNUM <= #END_ROW_NUM
ORDER BY ROWNUM;
IF EXISTS
(
SELECT *
FROM tempdb.dbo.sysobjects
WHERE ID = OBJECT_ID(N'tempdb..#UPLOAD_POLICY_HOLDER')
)
BEGIN
DROP TABLE #UPLOAD_POLICY_HOLDER
END
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION
SET #ERROR_NUMBER = ERROR_NUMBER()
SET #ERROR_SEVERITY = ERROR_SEVERITY()
SET #ERROR_STATE = ERROR_STATE()
SET #ERROR_PROCEDURE = ERROR_PROCEDURE()
SET #ERROR_LINE = ERROR_LINE()
SET #ERROR_MESSAGE = ERROR_MESSAGE()
EXEC P_INSERT_SQL_ERROR #ERROR_NUMBER, #ERROR_SEVERITY, #ERROR_STATE, #ERROR_PROCEDURE, #ERROR_LINE, #ERROR_MESSAGE
END CATCH
END
END
You can ignore the Leap_Year stuff - that was a separate attempt I'd made. The PH.DOB field is the one I'm having issues with. Previously I was just returning the DOB field, the CONVERT() was my attempt to get the value as a string so I could have more control.
My insert into Oracle code:
private void LoadDataIntoHSMVDBBulk(DataTable dt, string DestinationTableName, List ColumnMappings)
{
using (var bc = new OracleBulkCopy(GetConnectionString()))
{
bc.DestinationTableName = DestinationTableName;
bc.BulkCopyOptions = OracleBulkCopyOptions.UseInternalTransaction;
foreach (var colmapping in ColumnMappings)
{
var split = colmapping.Split(new[] { ',' });
bc.ColumnMappings.Add(split.First(), split.Last());
}
bc.BulkCopyTimeout = 20000;
bc.BatchSize = GetOracleBulkCountFromConfig();
bc.NotifyAfter = GetOracleBulkCountFromConfig();
bc.OracleRowsCopied += new OracleRowsCopiedEventHandler(bulkCopy_OracleRowsCopied);
bc.WriteToServer(dt);
bc.Close();
bc.Dispose();
dt.Clear();
}
}
I took an old copy of our project from several months ago and the dates are correct!! It seems the culprit is our version of the Oracle.DataAccess. When I point to Oracle 11g the dates are good, when I point to the newer Oracle 12c the dates are inverted. Any help is appreciated, but for now we're rolling the servers back to 11g.
This has been a problem for us as well and could not resolve it.
We've found workaround though which is not pretty but works. And is not a huge time consumer.
We bulkCopy close and after success we do update on Date type columns. Update should not take too long it is a bulk action.
Hope this helps. Cheers!
//EF 5.0.0.
private tables entities = new Tables();
private string validFrom; //try with date as well, should work
private int id;
using (OracleBulkCopy bulkCopy = new OracleBulkCopy(applicationContext.GetConnection(CrmContext.ConnectionEnum.CrmDatabase)))
{
bulkCopy.DestinationTableName = "TABLE";
bulkCopy.BulkCopyTimeout = 180;
bulkCopy.WriteToServer(dataTable);
bulkCopy.Close();
}
//this is a workaroud due to error in Oracle DataAccess Driver
//look at the
entities.Database.ExecuteSqlCommand("UPDATE TABLE SET DATE_FROM = TO_DATE(:p0,'DD.MM.YYYY.') WHERE ID = :p1", validFrom, id);
entities.SaveChanges();

IF Not Exist then Inseting a value in the table

Using SQL Server 2005, vb.net
Table1
Name FromDate ToDate
Raja 12/02/2010 14/02/2010
Ravi 14/02/2010 15/02/2010
Ramu 18/02/2010 21/02/2010
...,
Insert into Table1 values('" & textbox1.text & "', '" & textbox2.text & "'. '" & textbox3.text & "'", con)
When i try to insert a value into table1 it will compare the table values if it is same, It Should throw a error msg "Name and Date Already Exist" otherwise Insert a value.
Before Inserting i want to check a textbox value with table value.
Can any one give a sample idea or code for this.
In T-SQL:
IF EXISTS(SELECT * FROM dbo.Table1 WHERE Name = #Name AND FromDate = #FromDate AND ToDate = #ToDate)
RAISERROR (N'Values already exist', 10, 1)
ELSE
INSERT INTO dbo.Table1(Name, FromDate, ToDate)
VALUES(#Name, #FromDate, #ToDate)
And then call this from a parametrized query in your VB.NET code.
For details about RAISERROR, see the MSDN docs: http://msdn.microsoft.com/en-us/library/ms178592.aspx. The value "10" here is the severity, the "1" is the state. You can see a list of all available severities and states in the MSDN docs.
Or wrap the whole statement into a stored proc that deals with all of this, and just call that stored proc.
UPDATE:
Create a stored proc:
CREATE PROCEDURE dbo.InsertData(#Name VARCHAR(50), #FromDate DATETIME, #ToDate DAETIME)
AS BEGIN
BEGIN TRANSACTION
IF EXISTS(SELECT * FROM dbo.Table1 WHERE Name = #Name AND FromDate = #FromDate AND ToDate = #ToDate)
ROLLBACK TRANSACTION
RAISERROR (N'Values already exist', 10, 1)
ELSE
INSERT INTO dbo.Table1(Name, FromDate, ToDate)
VALUES(#Name, #FromDate, #ToDate)
COMMIT TRANSACTION
END
and then call that from your code (I'm not fluent in VB.NET - this is C#, but should be simple enough to translate):
using(SqlConnection _con = new SqlConnection('your connection string here'))
{
using(SqlCommand _cmd = new SqlCommand("InsertData", _con)
{
_cmd.CommandType = CommandType.StoredProcedure;
// add parameters as necessary
_cmd.Parameters.AddWithValue("#Name", "Your Name");
_cmd.Parameters.AddWithValue("#FromDate", "20100101");
_cmd.Parameters.AddWithValue("#ToDate", "20100331");
try
{
// open connection, execute stored proc, close connection
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
catch(SqlException sqlexc)
{
// handle SQL exception
}
}
}
That nicely encapsulates everything into a single method - does that work for you??
Use the "IF NOT EXIST" command
IF NOT EXISTS (SELECT * FROM Table WHERE YourContition) INSERT INTO Table (a,b) VALUES (#c1,#c2)

Asp.Net Gives a Timeout Error While Running a Stored Procedure

I am using asp.net, .NET 3.5, C#, and SQL Server Express 2005.
I have created a stored procedure in SQL, and when I run SP from SQL server it takes less than 1 second to return results. I have also tried that query in query analyzer and it also gives me results in less than 1 second. But when I try to call this SP from .NET (C#), it takes a long time, and then gives a timeout error.
Here is the code I am using to call the stored procedure:
SqlConnection con = new SqlConnection();
con.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
con.Open();
SqlCommand command = new SqlCommand("spReport_SiteUsage_KP", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#fromDate", SqlDbType.DateTime));
command.Parameters.Add(new SqlParameter("#toDate", SqlDbType.DateTime));
command.Parameters[0].Value = Convert.ToDateTime(DatePicker1.SelectedDate.ToShortDateString());
command.Parameters[1].Value = DatePicker2.SelectedDate;
int i = command.ExecuteNonQuery();
con.Close();
Store Procedure :
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spReport_SiteUsage_KP]
#fromDate datetime = null,
#toDate datetime = null
AS
truncate table dbo.RPT_SiteUsage
IF (#FromDate is not null and #ToDate is not null) --Hourly Report, grouped by hour
Begin
insert into RPT_SiteUsage
select '' as ReportType,
'Site Usage for '+ datename(mm,#fromDate)+' '+datename(dd,#fromDate)+', '+datename(yy,#fromDate) +
' To '+datename(mm,#toDate)+' '+datename(dd,#toDate)+', '+datename(yy,#toDate) as ReportTitle,
min(#fromDate) as FromDate,max(#toDate) as ToDate,
isnull(count(s.SessionId),0) VisitsTotal,
isnull(count(distinct(s.cookieid)),0) VisitsUnique,
isnull(sum(PagesVisited),0) PageViews,
isnull(round(avg(convert(decimal(10,2),PagesVisited)),2),0) PagePerVisit,
isnull(min(PagesVisited),0) MinNoPageViews,
isnull(max(PagesVisited),0) MaxNoPageViews,
isnull(round(avg(convert(decimal(10,2),TimeInSiteMinutes)),2),0) AvgTimeInSite,
isnull(min(TimeInSiteMinutes),0) MinTimeSpent,
isnull(max(TimeInSiteMinutes),0) MaxTimeSpent,
isnull(sum(NewPeople),0) as NewVisitors
from
dbo.UMM_UserAction ua inner join dbo.UMM_Session s on ua.SessionId=s.Sessionid
left join
(select ua.sessionId, datediff(ss,min(Actiondate),max(Actiondate))/60 TimeInSiteMinutes
from dbo.UMM_UserAction ua
where ActionDate between #fromDate and #toDate
group by ua.sessionid
) sessionTime on ua.sessionId = sessionTime.sessionid
left join
(select ua.sessionId, 0 as NewPeople
from dbo.UMM_UserAction ua
inner join dbo.UMM_Session s on ua.SessionId=s.SessionId
inner join dbo.UMM_Cookie c on s.CookieId=c.CookieId
where ua.actiondate< #fromDate --this is the from date
group by UserId,ua.sessionId
) Old on ua.sessionId = Old.sessionid
left join
(select ua.sessionId,count(distinct(uaP.PageEntryId)) as PagesVisited
from dbo.UMM_UserAction ua,
dbo.UMM_UserActionPageReview uaP
where ua.UserActionId=uaP.UserActionId
and ActionDate between #fromDate and #toDate
group by ua.sessionId
)pVisited on ua.sessionId = pVisited.sessionId
where ActionDate between #fromDate and #toDate
IF (select count(*) from RPT_SiteUsage)=0
insert into RPT_SiteUsage
select '(1 day)' as ReportType,
'Site Usage for '+datename(mm,#fromDate)+' '+datename(dd,#fromDate)+', '+datename(yy,#fromDate) +
' To '+datename(mm,#toDate)+' '+datename(dd,#toDate)+', '+datename(yy,#toDate) as ReportTitle,
min(#fromDate) as FromDate,max(#toDate) as ToDate,
0 as VisitsTotal,
0 as VisitsUnique,
0 as PageViews,
0 as PagePerVisit,
0 as MinNoPageViews,
0 as MaxNoPageViews,
0 as AvgTimeInSite,
0 as MinTimeSpent,
0 as MaxTimeSpent,
0 as NewVisitors
END
Another idea, the TimeOut of each SqlCommand is also controlled individually, so, you can control it with CommandTimeOut property.
command.CommandTimeout = 120;
However, I would check the execution plan to see where is it wasting or hogging db resources, I suggest this just for experiment, not on production.
Well - I would say there's an error in your connection string. Please check it.
If it takes long before the query returns an error, there is probably something wrong with your connection (string).
It could be the fun issue with a bad query plan cached on the proc. Especially if the guts of the proc just as a Query in Query Analyzer runs fine. Check this link out on how to resolve the situation: http://www.mssqltips.com/tip.asp?tip=1304

Categories

Resources