UpdateParameters with datetime - asp.net

I am trying to use the sqldatasource.UpdateParameters.Add() to add a date/time to my database table.
The column data type is smalldatetime and it is displaying in a gridview just fine. If I try end edit this date/time, then save the changes the other fields update, but the date/time remains the same. I have tried using the DateTime.Parse methods with no success.
sqlds1.UpdateParameters.Add("MeasurementDateTime", Data.DbType.DateTime, currentMsrmntDateTime.Text)
I use the above code for each respective value and parameter pair, but the date/time field doesn't update. The update statement again works for all parameters except the date/time.
CREATE PROCEDURE [dbo].[UpdateCathodeTemps]
(
#MeasurementTypeCode int
,#MeasurementDateTime smalldatetime
,#Value nvarchar(50)
,#Comments nvarchar(512)
,#IsMeasurementChecked bit
,#MeasurementCheckedBy nvarchar(50)
,#BakeDetailsID int
-- 7 Params
) AS
BEGIN TRANSACTION
UPDATE tblMeasurementsAtPeriod
SET MeasurementDateTime = #MeasurementDateTime,
Value = #Value,
Comments = #Comments,
MeasurementCheckedBy = #MeasurementCheckedBy,
IsMeasurementChecked = #IsMeasurementChecked,
MeasurementTypeCode = #MeasurementTypeCode,
BakeDetailsID = #BakeDetailsID
WHERE MeasurementDateTime = #MeasurementDateTime AND MeasurementTypeCode = #MeasurementTypeCode
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
No errors are thrown when I hit the save button, all the other fields are updated, but the date/time remains the same. I have checked the values as they are being passed to the stored procedure, and they are as I expect.

Here's your problem in the WHERE clause of your stored procedure:
WHERE MeasurementDateTime = #MeasurementDateTime AND
MeasurementTypeCode = #MeasurementTypeCode
So you are updating to the exact same date!
The where clause picks those rows with a given MeasurementDateTime, you then update those rows but the MeasurementDateTime that you are updating to is the same (obviously).
Perhaps you want 2 params:
,#OriginalMeasurementDateTime smalldatetime
,#NewMeasurementDateTime smalldatetime

I think your UPDATE query may be flawed -
You are trying to update MeasurementDateTime, but your WHERE clause is looking for records with the same value that you are trying to update MeasurementDateTime to, so you won't be updating the same records. You'll either update no records (if no records have that same value), or you'll be updating OTHER records.
That may be what you're trying to do, but it seems odd to me. It seems more logical to have another parameter for the previous value to search for and update them to the new value:
UPDATE tblMeasurementsAtPeriod
SET MeasurementDateTime = #NewMeasurementDateTime, /* NEW date value */
Value = #Value,
Comments = #Comments,
MeasurementCheckedBy = #MeasurementCheckedBy,
IsMeasurementChecked = #IsMeasurementChecked,
MeasurementTypeCode = #MeasurementTypeCode,
BakeDetailsID = #BakeDetailsID
WHERE MeasurementDateTime = #OldMeasurementDateTime /* OLD date value */
AND MeasurementTypeCode = #MeasurementTypeCode

Related

Return value to textbox from stored procedure

Having trouble returning the value ID value I need for output back to the textbox in the form. Webforms and ADO.net
I tried adding a param identity as an int and OUT clause, while setting identity = scope_identity and returning the value then using the pattern my team is currently using for ExecuteNonQuery with anonymous parameter classes passing in values and tried passing the #identity value to the textbox.text for the id.
DataManager.Db.ExecuteNonQuery("DefaultConnection", "usp_CreateNewSalesTerritory",
new SqlParameter("#orgId", orgId),
new SqlParameter("#identity", salesTerritoryIdTextBox.Text),
new SqlParameter("#salesTerritoryName", salesTerritories.Name),
new SqlParameter("#createdBy", salesTerritories.CreatedBy),
new SqlParameter("#createdDate", salesTerritories.CreatedDate),
new SqlParameter("#updatedBy", salesTerritories.UpdatedBy),
new SqlParameter("#updatedDate", salesTerritories.UpdatedDate),
new SqlParameter("#isActive", salesTerritories.IsActive));
CREATE PROCEDURE dbo.usp_CreateNewSalesTerritory
#orgId VARCHAR(255),
#salesTerritoryName VARCHAR(255),
#createdBy VARCHAR(255),
#createdDate DATETIME,
#updatedBy VARCHAR(255),
#updatedDate DATETIME,
#isActive BIT,
#identity INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO SalesTerritory (OrganizationId, Name, IsActive,
CreatedBy, CreatedDate, UpdatedBy, UpdatedDate)
VALUES (#orgId, #salesTerritoryName, #isActive,
#createdBy, #createdDate, #updatedBy, #updatedDate);
--SELECT SCOPE_IDENTITY();
--RETURN SCOPE_IDENTITY();
--SELECT ##IDENTITY;
SET #identity = SCOPE_IDENTITY()
END;
RETURN #identity
I expected to get the new inserted ID value for that record, instead, I get the default value of 0 on the screen
Normally, you would call such a stored procedure in "pure" ADO.NET using the .ExecuteNonQuery() method on the SqlCommand object - since it's an INSERT statement.
But now, your stored procedure is actually returning some data - so you really need to treat this like a "normal" SELECT stored procedure.
Assuming you're always returning just the SCOPE_IDENTITY() value - preferably like this:
SELECT SCOPE_IDENTITY();
which is just one single value - you can use the .ExecuteScalar() method on the SqlCommand object - something like this:
object returned = sqlCmd.ExecuteScalar();
if (returned != null)
{
int newIdValue = Convert.ToInt32(returned);
}
// else -> nothing was returned, so most likely no row has been inserted -> handle it appropriately
So maybe you already have a "wrapper" method for .ExecuteScalar() on your DataManager.Db object - or maybe you need to add it. Give it a try - I'm pretty sure this will solve the issue.
I would avoid using the RETURN ... statement - SQL Server stored procedure by default will always return the number of rows that were affected by your stored procedure - don't change that "standard" behavior, if you can.

SQLite trigger after update

My table has timestamp column. I want a trigger which sets timestamp to 0 on affected rows when a row is updated and the timestamp is not specified in the update statement.
If I use this trigger:
CREATE TRIGGER AFTER UPDATE ON mytable FOR EACH ROW
WHEN (NEW.timestamp IS NULL)
BEGIN
UPDATE mytable SET timestamp = 0 WHERE id = NEW.id;
END;
then the trigger doesn't fire for this update statement:
UPDATE mytable SET comecolumn='some'
I.e. timestamp of affected rows doesn't change to 0.
Can you please help me define the trigger?
The only way to make additional changes to a row in an UPDATE trigger is to execute another UPDATE on the same table afterwards.
The only way to detect whether a column value is changed is to compare the old and the new row values; the trigger does not know which columns actually were mentioned in the original UPDATE statement.
To prevent the trigger from triggering itself recursively, you should restrict it to be triggered by changes of all columns except the timestamp:
CREATE TRIGGER clear_timestamp
AFTER UPDATE OF all_the, other, columns ON MyTable
FOR EACH ROW
WHEN OLD.timestamp = NEW.timestamp
BEGIN
UPDATE MyTable
SET timestamp = 0
WHERE id = NEW.id;
END;
I think the problem is that in the SET statement is expanded to every column, with every column set to the current value in the database. So the original only trigger works, if the current timestamp column is NULL.
A solution could be to create another trigger that resets the timestamp column to NULL before an UPDATE.
CREATE TRIGGER "set_null"
BEFORE UPDATE ON "mytable" FOR EACH ROW
BEGIN
UPDATE mytable set timestamp = NULL where rowid = NEW.rowid;
END
This way the NEW.timestamp is NULL if it is not specified in the UPDATE SET.
Obviously now a NOT NULL constraint cannot be set on timestamp.
Another problem is that trigger recursion must be off when executing a update query:
PRAGMA recursive_triggers = OFF;
Here is another way:
import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
name = {'name':'jack'}
c.execute("""CREATE TABLE Programs (
id INTEGER PRIMARY KEY,
name VARCHAR(64) NOT NULL,
time_added INTEGER
);""")
c.execute("""CREATE TRIGGER program_time_added AFTER INSERT ON Programs
FOR EACH ROW
BEGIN
UPDATE Programs SET time_added =datetime('now', 'localtime') WHERE id = NEW.id;
END;""")
c.execute('INSERT INTO Programs (name) VALUES (?)', [name['name']])

Incorrect default value passed to the SQL Server database

I have set my column to int not null default 1... but whenever I save my record, it sets default value for that record to be 0.
I am not setting it anywhere. I don't know where I am making a mistake.
I have debugged my code , and when I am passing new entity object it is setting default value for not null to 0 .May be it is something with LINQ, But I don't know how to handle it.I don't want to explicitly assign value.
Thanks!
For sql-server, you can use SQL Server Profiler to catch all the scripts you run into the DB.
This may show you some details
Try running this query, replacing the 'myTable' and 'myColumn' values with your actual TABLE and COLUMN names, and see what's returned:
SELECT
OBJECT_NAME(C.object_id) AS [Table Name]
,C.Name AS [Column Name]
,DC.Name AS [Constraint Name]
,DC.Type_Desc AS [Constraint Type]
,DC.Definition AS [Default Value]
FROM sys.default_constraints DC
INNER JOIN sys.Columns C
ON DC.parent_column_id = C.column_id
AND DC.parent_object_id = C.object_id
WHERE OBJECT_NAME(DC.parent_object_id) = 'myTable'
AND COL_NAME(DC.parent_object_id,DC.parent_column_id) = 'myColumn'
;
Should return something like this:
[Table Name] [Column Name] [Constraint Name] [Constraint Type] [Default Value]
-------------------------------------------------------------------------------------------
myTable myColumn DF_myTable_myColumn DEFAULT_CONSTRAINT ('0')
If the [Default Value] returned is indeed (1), then it means that you have set the constraint properly and something else is at play here. It might be a trigger, or some other automated DML that you've forgotten/didn't know about, or something else entirely.
I am not the world's biggest fan of using a TRIGGER, but in a case like this, it could be handy. I find that one of the best uses for a TRIGGER is debugging little stuff like this - because it lets you see what values are being passed into a table without having to scroll through mountains of profiler data. You could try something like this (again, switching out the myTable and myColumn values with your actual table and column names):
CREATE TABLE Default_Check
(
Action_Time DATETIME NOT NULL DEFAULT GETDATE()
,Inserted_Value INT
);
CREATE TRIGGER Checking_Default ON myTable
AFTER INSERT, UPDATE
AS
BEGIN
INSERT INTO Default_Check (Inserted_Value)
SELECT I.myColumn
FROM Inserted I
;
END
;
This trigger would simply list the date/time of an update/insert done against your table, as well as the inserted value. After creating this, you could run a single INSERT statement, then check:
SELECT * FROM Default_Check;
If you see one row, only one action (insert/update) was done against the table. If you see two, something you don't expect is happening - you can check to see what. You will also see here when the 0 was inserted/updated.
When you're done, just make sure you DROP the trigger:
DROP TRIGGER Checking_Default;
You'll want to DROP the table, too, once it's become irrelevant:
DROP TABLE Default_Check;
If all of this still didn't help you, let me know.
In VB use
Property VariableName As Integer? = Nothing
And
In C# use
int? value = 0;
if (value == 0)
{
value = null;
}
Please check My Example:
create table emp ( ids int null, [DOJ] datetime NOT null)
ALTER TABLE [dbo].[Emp] ADD CONSTRAINT DF_Emp_DOJ DEFAULT (GETDATE()) FOR [DOJ]
1--Not working for Default Values
insert into emp
select '1',''
2 ---working for Default Values
insert into emp(ids) Values(13)
select * From emp

PL/SQL UPDATE -- Well, not updating

I am using a procedure
CREATE OR REPLACE PROCEDURE update_rec(
page_id IN SSC_Page_Map.Page_ID_NBR%TYPE,
page_type IN SSC_Page_Map.Page_Type%TYPE,
page_dcpn IN SSC_Page_Map.Page_Dcpn%TYPE)
IS
BEGIN
UPDATE SSC_Page_Map
SET Page_Type = page_type,
Page_Dcpn = page_dcpn
WHERE Page_ID_NBR = page_id;
COMMIT;
END;
to update my database table row. I confirm the procedure execute correctly but I don't see the update. I have commented out the update to confirm I have permission to modify the database and that succeeds.
SET Page_Type = page_type updates the column with the current column value.
The visibility rules inside a PL/SQL program are such that the column name takes precedence over your parameter name. Give your parameters a different name and everything should be fine. A common coding convention is to prepend the parameters with p_ to identify them as parameters:
CREATE OR REPLACE PROCEDURE update_rec(p_page_id IN SSC_Page_Map.Page_ID_NBR%TYPE,
p_page_type IN SSC_Page_Map.Page_Type%TYPE,
p_page_dcpn IN SSC_Page_Map.Page_Dcpn%TYPE)
IS
BEGIN
UPDATE SSC_Page_Map
SET Page_Type = p_page_type,
Page_Dcpn = p_page_dcpn
WHERE Page_ID_NBR = p_page_id;
COMMIT;
END;
Use aliases for zero ambiguity:
CREATE OR REPLACE PROCEDURE update_rec(
page_id IN SSC_Page_Map.Page_ID_NBR%TYPE,
page_type IN SSC_Page_Map.Page_Type%TYPE,
page_dcpn IN SSC_Page_Map.Page_Dcpn%TYPE)
IS
BEGIN
UPDATE SSC_Page_Map
SET Page_Type = update_rec.page_type,
Page_Dcpn = update_rec.page_dcpn
WHERE SSC_Page_Map.Page_ID_NBR = update_rec.page_id;
COMMIT;
END;
(Note: I have seen one case where someone added a column called something like p_xyz to a table, which caused no end of trouble for the client whose naming convention had p_ for all procedure/function parameters. The alias method, in contrast, works 100% of the time.)

Set a due date column using a trigger

I'm working on a Sqlite database where a table has both a initial_date column and a due_date one. I'd like to automatically set the latter's value using a trigger every time the former one's value is changed, but something doesn't works.
Here's a simplified versione of the table DDL
CREATE TABLE timetable (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
initial_date DATETIME,
due_date DATETIME
);
As you can see, the two DATETIME columns allow NULL value; this is because in the real table I'd like to insert rows without setting the initial_date and update those rows later for setting the initial_date.
This is the trigger I added
CREATE TRIGGER [timetable-due-date] AFTER UPDATE ON timetable
BEGIN
UPDATE timetable
SET due_date = DATE( NEW.initial_date, '+ 10 days' )
WHERE id = NEW.id
AND NEW.initial_date IS NOT NULL;
END;
but it doesn't fires. If I execute UPDATE timetable SET initial_date='2013-10-04' WHERE id=1, due_date keeps the initial NULL value.
I also tried using the CREATE TRIGGER ... AFTER UPDATE OF initial_date ON ... variant, but without any luck.
I'm surely doing something really stupid here, but I can't figure what.
Thank you for your help.
The syntax of your date modifier is wrong; there must be no space between the + and the number:
CREATE TRIGGER "timetable-due-date"
AFTER UPDATE OF initial_date ON timetable
WHEN NEW.initial_date IS NOT NULL
BEGIN
UPDATE timetable
SET due_date = DATE(new.initial_date, '+10 days')
WHERE id = NEW.id;
END;

Resources