Conditional update of SQL Server table column - sql-server

I have to update a table (say table name is Venues in SQL Server conditionally i.e. if a column (say column name is Venue_Name) in Venues CONTAINS sub-string 'C_' then SET a column (say column name is Venue_Type) in Venues = Conference.
I have tried this query as:
IF Venue_Name CONTAINS 'C_'
UPDATE Venues SET Venue_Type = 'Conference'
ELSE IF Venue_Name CONTAINS 'J_'
UPDATE Venues SET Venue_Type = 'Journal'
ELSE
UPDATE Venues SET Venue_Type = 'Other'
But found error at using the keyword CONTAINS.

What you need is a CASE expression:
UPDATE Venues
SET Venue_Type = CASE
WHEN Venue_Name LIKE '%C[_]%' THEN 'Conference'
WHEN Venue_Name LIKE '%J[_]%' THEN 'Journal'
ELSE 'Other'
END

Related

SQL Server Merge Statement to return zero if no record for an id

I am using a merge statement to update the number of courses complete in the ModuleEnrollment table. This works but however if a course is removed from an Employee, then it still remains at its previous value. Is there a way to include in the merge statment to return 0 for any EmployeeID not included in the CoursesComplete Table.
MERGE [dbo].[ModuleEnrollment] as ME
USING [dbo].[CoursesComplete]AS CC
ON ME.[EmployeeID] = CC.[EmployeeID] AND ME.[ModuleID] = CC.[ModuleID]
WHEN MATCHED THEN
UPDATE SET ME.[CoursesComplete]=CC.[CoursesComplete]
WHEN NOT MATCHED BY TARGET THEN
INSERT([EmployeeID],[ModuleID],[CoursesComplete]) VALUES(CC.
[EmployeeID],CC.[ModuleID],CC.[CoursesComplete]);
GO
You just have to add:
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET ME.[CoursesComplete]=0
The whole query:
;MERGE [dbo].[ModuleEnrollment] as ME
USING [dbo].[CoursesComplete]AS CC
ON ME.[EmployeeID] = CC.[EmployeeID] AND ME.[ModuleID] = CC.[ModuleID]
WHEN MATCHED THEN
UPDATE SET ME.[CoursesComplete]=CC.[CoursesComplete]
WHEN NOT MATCHED BY TARGET THEN
INSERT([EmployeeID],[ModuleID],[CoursesComplete]) VALUES(CC.
[EmployeeID],CC.[ModuleID],CC.[CoursesComplete])
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET ME.[CoursesComplete]=0;

How to get Option Set Description field in MSCRM

I've tried to find where Option Set descriptions are stored in CRM's database. After research on the internet I've found that Option Set data is stored in the StringMap SQL table but this table doesn't contain description Field I want.
Does anyone know where Option Set descriptions are stored stored in CRM's SQL database? Below is a screenshot highlighting the field value I'm looking for:
Try this:
SELECT Label FROM [LocalizedLabelView] llv
join [AttributePicklistValueView] apvv on llv.ObjectId = apvv.AttributePicklistValueId
join [OptionSetView] osw on apvv.OptionSetId = osw.OptionSetId
join [AttributeView] aw on osw.OptionSetId = aw.OptionSetId
where aw.Name = 'fieldname' and llv.ObjectColumnName = 'Description'
This works for both global and non-global option sets, you just have to put as fieldname the name of the attribute on the entity (not a name of global option set). Of course to handle only global option sets you will not need the last join, simply do osw.Name = 'globaloptionsetname'
This seems to work:
SELECT DISTINCT l.Label
FROM MetadataSchema.LocalizedLabel l
LEFT JOIN MetadataSchema.AttributePicklistValue ap ON l.ObjectId = ap.AttributePicklistValueId
LEFT JOIN MetadataSchema.OptionSet os ON os.OptionSetId = ap.OptionSetId
WHERE l.ObjectColumnName = 'Description' AND os.Name = '<OPTIONSET_NAME>' AND ap.Value = <OPTIONSET_VALUE>
There are two parameters in the above script that you need to modify:
<OPTIONSET_NAME> must be replaced with the schema name of your optionset and prefixed with the entity's schema name. For example, if your optionset is called new_businessTypes and it's on the account entity, then <OPTIONSET_NAME> would be replaced with 'account_new_businesstypes'.
<OPTIONSET_VALUE> must be replaced with the integer value of the option you're looking for. In your example screenshot, that value is 2.

How to select columns with other name in linq?

I select my records in SQL Server Query as you seen below:
SELECT ProductName 'Some Name1' ,
Payment 'Some Name2'
FROM dbo.PrefactorProduct
Is there a way to select records like that in linq queries?
You can project result from your query to an Anonymous type and use different alias/field names for your fields.
var query = db.PrefactorProduct
.Select(r=> new
{
SomeName1 = r.ProductName,
SomeName2 = r.Payment
});
But if you are trying to format your result set for displaying purpose then you should look in to assigning column names for your grid/ data container.

Xml column attributes manipulation in sql server

I have a table named User in my database. In that there is a xml column named XmlText which contains lots of attributes.
<userDetails>
<MobileVerified>True</MobileVerified>
<EmailVerified>True</EmailVerified>
<IPAddress>122.160.65.232</IPAddress>
<Gender>Male</Gender>
<DateOfBirth>1970-03-22T00:00:00</DateOfBirth>
<DealingInProperties>residential_apartment_flat</DealingInProperties>
<DealingInProperties>residential_villa_bungalow</DealingInProperties>
<DealingInProperties>residential_farm_house</DealingInProperties>
</userDetails>
What is needed to do is i have to merge all the 'residential_villa_bungalow' values to 'residential_apartment_flat' if 'residential_apartment_flat' exists in the XmlText Column else 'residential_apartment_flat' will be left by default. There are approx 700000 record in the database so keep in mid that what technique can be used among normal update vs cursot.
Fire query with following columns "UserID,XmlText"
Probable logic wud be something like this..
if ('residential_villa_bungalow') exists
(
if ('residential_apartment_flat') exists
remove the 'residential_villa_bungalow' node as there must be only one 'residential_apartment_flat' node
else
update 'residential_villa_bungalow' into 'residential_apartment_flat'
)
XML Data Modification Language (XML DML)
-- Delete bungalow where already exist a flat
update YourTable
set XMLText.modify('delete /userDetails/DealingInProperties[. = "residential_villa_bungalow"] ')
where XMLText.exist('/userDetails[DealingInProperties = "residential_apartment_flat"]') = 1 and
XMLText.exist('/userDetails[DealingInProperties = "residential_villa_bungalow"]') = 1
-- Change value from bungalow to flat
update YourTable
set XMLText.modify('replace value of (/userDetails/DealingInProperties[. = "residential_villa_bungalow"]/text())[1]
with "residential_apartment_flat"')
where XMLText.exist('/userDetails[DealingInProperties = "residential_villa_bungalow"]') = 1

Why triggers try to insert NULL value when using a field from 'inserted' table?

I have to sync changes done in MSSQL with a remote MySQL database. The changes to be synced are adding invoices and users to the system. The remote server is not expected to be always reachable so I'm trying to set up a kind of log table for storing changes done in MSSQL.
Here is a fully working trigger for that:
CREATE TRIGGER [dbo].[dokument_insert]
ON [dbo].[dokument]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [bcg_ekodu].[dbo].[sync_stack] (event,sql, table_name, import_priority)
SELECT
'INSERT',
'INSERT INTO bills SET
date = "'+CONVERT(VARCHAR(19),dok_kuup,120)+'",
total = "'+CAST(kokkusum AS nvarchar)+'",
number = "'+RTRIM(dok_nr)+'",
created = "'+CONVERT(VARCHAR(19),savetime,120)+'",
rounded = "'+CAST(ymardus AS nvarchar)+'",
currency = "'+CAST(valuuta AS nvarchar)+'",
due_date = "'+CONVERT(VARCHAR(19),tasupaev,120)+'",
pk_joosep = "'+CAST(dok_kood AS nvarchar)+'",
joosep_hankija = "'+CAST(hankija AS nvarchar)+'";
UPDATE
bills, users, companies
SET
bills.user_id = users.id,
bills.imported = NOW()
WHERE
bills.imported IS NULL
AND companies.id = users.company_id
AND companies.pk_joosep = 10
AND bills.user_id = users.pk_joosep',
'bills',
'200'
FROM inserted
END
It inserts a row into 'sync_stack' table every time a row is inserted to 'dokument' table. The 'sql' column will contain an SQL to create the same kind of row in another (MySQL) database.
But this trigger is not working:
CREATE TRIGGER [dbo].[klient_insert]
ON [dbo].[klient]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [bcg_ekodu].[dbo].[sync_stack] (event,sql, table_name, import_priority)
SELECT
'INSERT',
'INSERT INTO users SET
username =10'+CAST(kl_kood as nvarchar)+',
password = NULL,
name ="'+LTRIM(RTRIM(kl_nimi))+'",
email ="'+CAST(LTRIM(RTRIM(kl_email)) as nvarchar)+'",
reference_no ="'+CAST(LTRIM(RTRIM(kl_viide)) as nvarchar)+'",
phone ="'+CAST(LTRIM(RTRIM(kl_tel1)) as nvarchar)+'",
logins ="'+CAST(0 as nvarchar)+'",
last_login = NULL,
created ="'+CONVERT(VARCHAR(19),savetime,120)+'",
updated = NULL,
deleted ="0",
address ="'+CAST(LTRIM(RTRIM(kl_aadr1)) as nvarchar)+'",
pk_joosep ="'+CAST(kl_kood as nvarchar)+'"',
'users',
'210'
FROM inserted
END
While the execution of the above SQL to create that trigger completes just fine, when I try to insert some rows to the 'triggered' table, I get the following error:
No row was updated.
The data in row 175 was not committed.
Error Source: .Net SqlClient Data Provider.
Error Message: Cannot insert the value NULL into column 'sql', table 'mydb.dbo.sync_stack'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Correct the errors and retry or press ESC to cancel the change(s).
If I delete this trigger, this error does not occur.
If I insert just plain text for 'sql' column, it works as expected.
If I use any field from the inserted row, even just a text field, it fails again.
If I allow NULL values in 'sql' column, inserting rows succeeds but I get a NULL value in 'sql' column.
How to make the second trigger work as expected, too?
I suspect that at least one of the values from inserted that you are concatenating into your SQL statement is NULL. You can circumvent this by using COALESCE, e.g.
username =10'+COALESCE(CAST(kl_kood as nvarchar), '')+',
Of course you shouldn't be declaring nvarchar without specifying a length, right?
Bad habits to kick : declaring VARCHAR without (length)
Concatenating any value to NULL is NULL:
select 'test' + NULL
Results in null, you should use something like that for your columns:
select isnull(column, '')
This would result in an empty string.

Resources