SSIS Merge Statment Datetime not updated - datetime

I am using Merge Statement in my SSIS package. The problem is that it doesn't update the datetime column when i run the package. It inserts the datetime correctly but doesn't update them from NULL to some datetime if a new datetime is available in source database.
Both source and destination has same column type (datetime(2),null).
I am using the code below in SQL Task after truncating staging table.
MERGE abc.dbo.invoices AS targe
USING (SELECT
ID
,cash_received_date
,schedule_datetime
,delivery_date
FROM Staging.dbo.tmpabcinvoices) AS sourc
ON targe.id = sourc.id
WHEN MATCHED and
targe.schedule_datetime <> sourc.schedule_datetime
or
targe.delivery_date <> sourc.delivery_date
or
targe.cash_received_date <> sourc.cash_received_date
THEN UPDATE SET
,targe.schedule_datetime=sourc.schedule_datetime
,targe.delivery_date=sourc.delivery_date
,targe.cash_received_date=sourc.cash_received_date
WHEN NOT MATCHED THEN
INSERT(
old_invoiceid
,cash_received_date
,schedule_datetime
,delivery_date
)
VALUES
(
sourc.old_invoiceid
,sourc.cash_received_date
,sourc.schedule_datetime
,sourc.delivery_date
);
GO

You have a comma which shouldn't be there at the start of this line:
,targe.schedule_datetime=sourc.schedule_datetime
Also, you'll need to add this to take care of the NULLs:
targe.schedule_datetime <> sourc.schedule_datetime
or (targe.schedule_datetime IS NULL AND sourc.schedule_datetime IS NOT NULL)
or targe.delivery_date <> sourc.delivery_date
or (targe.delivery_date IS NULL AND sourc.delivery_date IS NOT NULL)
or targe.cash_received_date <> sourc.cash_received_date
or (targe.cash_received_date IS NULL AND sourc.cash_received_date IS NOT NULL)
While ANSI_NULLS is set to ON, NULLs are basically unknowns, so they can't be evaluated to either 'equal to' or 'not equal to'.

Related

Stored Procedure Update

I want to insert those values also which have version null and and for version null I don't have status.
I am getting all data from datatable to procedure table type and then how do I check that the incoming data has version null or not?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[uspInsertFilterData]
#sqlDataTable SqlTableType READONLY
AS
BEGIN
IF (#sqlDataTable.Version IS NOT NULL OR #sqlDataTable.Version != '')
BEGIN
INSERT INTO FilterCombination (Version, HotFix, Resourcetype, Language)
(SELECT
t1.Product, t1.Version, t1.HotFix, t1.Resourcetype,
t1.Language
FROM
#sqlDataTable t1, Product_Version_Mapping t2
WHERE
t1.Product = t2.Product
AND t1.Version = t2.Version
AND t2.Status = 'Correct')
END
ELSE
BEGIN
INSERT INTO FilterCombination (Product, Version, HotFix, Resourcetype, Language)
(SELECT
t1.Product, t1.Version, t1.HotFix, t1.Resourcetype, t1.Language
FROM
#sqlDataTable t1, Product_Version_Mapping t2
WHERE
t1.Product = t2.Product);
END
END
This query is not working. Please help
For checking null values, you can use NULLIF like so...
IF NULLIF(#PreviousStartDate, '') IS NULL
Please refer below link.
Check if a parameter is null or empty in a stored procedure

<SQLITE> compare old value and new value

I have a trigger.
I want to do insert changed values after every update.
But I get syntax error on line IF .. THEN, and I can't find example.
IF (IFNULL(NEW.symbol,'') <> IFNULL(OLD.symbol,'')) THEN
INSERT INTO LOG(old_value, new_value, DATA, user)
VALUES ('Symbol: '|| IFNULL(OLD.symbol,''), 'Symbol: ' (IFNULL(NEW.symbol,''), CURRENT_TIMESTAMP, id_user)
Can You help me?
SQLite has no IF statement.
You must put the condition into the WHEN clause of the trigger.

Modify a column to NULL - Oracle

I have a table named CUSTOMER, with few columns. One of them is Customer_ID.
Initially Customer_ID column WILL NOT accept NULL values.
I've made some changes from code level, so that Customer_ID column will accept NULL values by default.
Now my requirement is that, I need to again make this column to accept NULL values.
For this I've added executing the below query:
ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL
I'm getting the following error:
ORA-01451 error, the column already allows null entries so
therefore cannot be modified
This is because already I've made the Customer_ID column to accept NULL values.
Is there a way to check if the column will accept NULL values before executing the above query...??
You can use the column NULLABLE in USER_TAB_COLUMNS. This tells you whether the column allows nulls using a binary Y/N flag.
If you wanted to put this in a script you could do something like:
declare
l_null user_tab_columns.nullable%type;
begin
select nullable into l_null
from user_tab_columns
where table_name = 'CUSTOMER'
and column_name = 'CUSTOMER_ID';
if l_null = 'N' then
execute immediate 'ALTER TABLE Customer
MODIFY (Customer_ID nvarchar2(20) NULL)';
end if;
end;
It's best not to use dynamic SQL in order to alter tables. Do it manually and be sure to double check everything first.
Or you can just ignore the error:
declare
already_null exception;
pragma exception_init (already_null , -01451);
begin
execute immediate 'alter table <TABLE> modify(<COLUMN> null)';
exception when already_null then null;
end;
/
You might encounter this error when you have previously provided a DEFAULT ON NULL value for the NOT NULL column.
If this is the case, to make the column nullable, you must also reset its default value to NULL when you modify its nullability constraint.
eg:
DEFINE table_name = your_table_name_here
DEFINE column_name = your_column_name_here;
ALTER TABLE &table_name
MODIFY (
&column_name
DEFAULT NULL
NULL
);
I did something like this, it worked fine.
Try to execute query, if any error occurs, catch SQLException.
try {
stmt.execute("ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL");
} catch (SQLException sqe) {
Logger("Column to be modified to NULL is already NULL : " + sqe);
}
Is this correct way of doing?
To modify the constraints of an existing table
for example... add not null constraint to a column.
Then follow the given steps:
1) Select the table in which you want to modify changes.
2) Click on Actions.. ---> select column ----> add.
3) Now give the column name, datatype, size, etc. and click ok.
4) You will see that the column is added to the table.
5) Now click on Edit button lying on the left side of Actions button.
6) Then you will get various table modifying options.
7) Select the column from the list.
8) Select the particular column in which you want to give not null.
9) Select Cannot be null from column properties.
10) That's it.

The Link Between Webform Combobox Data and the Database (SQL Server & ASP.NET)

The title, while long, pretty much says it all.
What I have is a master table with a bunch of supporting table relations through foreign keys. For a few of the foreign tables, upon attempting to insert a record into the master table where one of the foreign keys doesn't exist, the data would be passed to the foreign table to create the record first, thereby making the constraint valid and passing the key to the created record back to the insert procedure of the master table.
This data comes from a form in String form, but naturally the foreign key will be an int. The process would look something like this:
-- ASP.NET Web Form --
Requestor Name: _____________ (combobox)
Request: _____________ (dropdownlist)
Date: _____________ (datepicker)
This is a super simplified version, but assume we have a master table with the above data, where both names are foreign keys to a People table. The name fields are comboboxes with a populated list of names linking to People. However, if I wanted to enter a person who didn't yet exist in the People table, the procedure should first create the Person, then use the ID from that new record as the foreign key in the Master table containing columns for the above.
I'm using SQL Server and ASP.NET with VB.NET codebehind. I've been scratching my head over this one for awhile, how to pass data (in different forms such as a foreign key or string) between the web server and DB server, as well as where to validate / transform the data.
It seems the entered name will be passed as an ID if the foreign key exists, and a String if not.
This is my most perplexing problem so far, and no idea where else to look. I've read up on Scott Mitchell's site and others.
MY SOLUTION (?)
The best I can come up with is to pass the user input from the user as a string and convert it to int in the T-SQL procedure. If the value was selected from the drop down, it should match precisely with a valid foreign key. If it doesn't match, then create a new Person and return a foreign key. Is this best practice?
This seems complicated because it is. You have to get your hands dirty. If you need a relational database with ACID support, there's no auto-magical way of getting around it.
Relational databases 101: The primary key must exist before the foreign key can be populated (This is the reason why data warehouse developers populate the dimension table before the fact table). You'll have to design the logic to validate that the primary key exists, insert and get the key if not, and just get the key if exists.
Here's my implementation. I don't know if it's the best, but it worked well for me. Basically I take the values from the controls; in the case of the combobox I need the values from both the TextBox and DropDownList. I then pass those values to the following function in my codebehind:
'This method determines if the name selected already exists in the selection
' options and if so assigns the corresponding ID value to an object variable,
' if not it assigns the value of the `TextBox` to the variable.
Protected Function _ValidateValues(ByRef ddl As DropDownList, ByRef cb As TextBox) As Object
'Ensures the selected value is valid by checking against the entered value in the textbox
If Not String.IsNullOrEmpty(cb.Text) Then
If ddl.Items.Count > 0 Then
If StrComp(cb.Text, ddl.SelectedItem.ToString) = 0 Then
Return ddl.Items.Item(ddl.SelectedIndex).Value 'Returns the index of dropdown selected name
End If
End If
'This counts the capital letters in the entered value and if fewer than 2
' auto capitalizes the first letters. This also allows for project code
' names such as "DOORS" and people names such as "Allen McPherson" etc.
' Be careful though because if "allen McPherson" is entered, it will NOT
' be corrected, though it displays correctly.
Dim rg As New Regex("[A-Z]")
Dim mc As MatchCollection = rg.Matches(cb.Text)
If mc.Count < 2 Then
Return StrConv(cb.Text, VbStrConv.ProperCase)
Else : Return cb.Text
End If
End If
'Returns a SQL DB NULL object if an empty string is submitted
Return DBNull.Value
End Function
Then my stored procedure handles the values something like so...
(Forgive me if I neglected to replace some of the values. I tried to catch them all.)
CREATE PROCEDURE spInsertUser
#User nvarchar(50) = NULL,
#Role nvarchar(50) = NULL,
#RecordID int output -- Returned Value
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- CHECK IF USER EXISTS
-- Insert new record to Users table if the requested user doesn't exist
-- Needed to ensure that the foreign keys are relevant
IF #User = '' OR #User IS NULL BEGIN SET #User = NULL SET #RecordID = NULL END --Ensures that an empty string cannot be submitted, thereby causing an error.
ELSE BEGIN
declare #forename varchar(50), #surname varchar(50)
declare #uid table (ID int)
declare #users table (ID smallint, Name nvarchar(50))
insert into #users
select ID, Name from Users
--If the value can be converted into an int, we need go no further.
BEGIN TRY SET #RecordID = CONVERT(smallint, #User) END TRY
BEGIN CATCH
BEGIN TRY --Otherwise, attempt to parse the name
Set #User = LTRIM(RTRIM(#User)) --Trim the extra space at the beginning and end. This ensures the following "IF" test will evaluate properly.
IF NOT CHARINDEX(' ', #User) > LEN(#User) AND CHARINDEX(' ', #User) > 0 BEGIN -- Confirm First & Last Name exist
Set #forename = RTRIM(LEFT(#User, CHARINDEX(' ',#User,0)-1))
Set #surname = LTRIM(RIGHT(#User, LEN(#User) - CHARINDEX(' ',#User,0)))
Set #User = #forename + ' ' + #surname --Ensure that there is a valid First & Last name
IF LEN(#forename) > 1 AND LEN(#surname) > 1 BEGIN -- Confirm First & Last Name exist
--First ensure that the User doesn't already exist, and if
-- so use their ID, if not insert the new User.
IF NOT EXISTS (select Name from #users where Name like #User) BEGIN --Check if the user already exists
INSERT INTO Users (Name, Forename, Surname) OUTPUT INSERTED.ID INTO #uid Values (#User, -- If not, insert them
#forename, #surname) --Nicely manicured first, last, and full names
SET #RecordID = CONVERT(smallint, (select MAX(ID) from #uid)) END -- Now set the Role to the ID of the new user
ELSE BEGIN --Otherwise if the user already exists, set the Role to the ID of that user
SET #RecordID = (select ID from #users where Name like #User) END
IF NOT EXISTS (select * from rUsersInRoles where UserID = #RecordID) BEGIN
--Do some string manipulation to increase the chances of matching the role
SET #Role = REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(#Role)), ' ', '%'), '.', '%'), '#', '%') --Trims & replaces spaces & periods with wildcards
INSERT INTO rUsersInRoles (UserID, UserRoleID) VALUES
(#RecordID, (select top 1 ID from rUserRoles where Role like #Role)) END
END
END
END TRY
BEGIN CATCH END CATCH
END CATCH
END
END
This stored procedure deals with the case of User Roles as well. If the more simple case of Users only is needed, simply remove the clauses dealing with the checking and insertion of User Roles. :)

SQL: Not equal operator Problem

I am using a not equal operator <> in my sql statement but it doesn't retrieve any record which is not equal to the selected date.
CODE:
Command = New SqlCommand("SELECT * FROM [Products] WHERE [ParkingStartDate] <> #StartDate", myConn)
Command.Parameters.AddWithValue("#StartDate", StartDate1)
This won't return anything if either of the following is true:
StartDate1 is a NULL
ParkingStartDate for all values is a NULL or equal to StartDate1 (obvious one)
Check that you are passing a non-NULL value in StartDate1 and there are records satisfying your condition.
If the values are null you would have to do
Command = New SqlCommand("SELECT * FROM [Products] WHERE [ParkingStartDate] <> #StartDate OR ParkingStartDate is null", myConn)
Command.Parameters.AddWithValue("#StartDate", StartDate1)
First stop using that <> operator.
Use instead != (NOT EQUAL)
run this statement in sql. it will return zero results. to illustrate my point.
select '1' where NULL <> 0
instead use
where columname != #startdate or columnname is null
One important thing to take into consideration when dealing with querying based on date is that the date in SQL Server is treated as exact as the date you send in. So, if you pass in a full date/time, like 2011-10-24 14:35:29, it will return all dates that are not that exact date. If you are looking for a particular portion of that date to be selected against, you need to only give that portion of the date. Using the DATEPART command will help here also.
If the value is undefined, it is not included in <> or != clause.
Along with these you can use sql function 'COALESCE()' to include rows having undefined cells.
"SELECT * FROM [Products] WHERE COALESCE([ParkingStartDate],'') <> #StartDate OR ParkingStartDate is null"
Hope it will help you.
My recommendation would be to try with NULLIF operator. Modify your query to be like :
SELECT * FROM [Products] WHERE NULLIF([ParkingStartDate], #StartDate) IS NOT NULL OR ParkingStartDate is NULL
Hope this helps.

Resources