Inserting/Updating a SQL Server table using stored procedure in BizTalk - sql-server

I am currently working on getting a set of records from a view in the Oracle database and trying to insert/update them in to the table in the SQL Server table depending on a column using BizTalk.
For this I created a stored procedure:
Create PROCEDURE [dbo].[uspInsertorUpdateDepartment]
#dept_name varchar(64),
#jax_dept_id char(32)
AS
BEGIN
SET NOCOUNT ON;
IF (SELECT TOP (1) 1 FROM afm.[jax_dept]
WHERE jax_dept_id = #jax_dept_id) IS NULL
INSERT INTO afm.[jax_dept](dept_name, jax_dept_id)
VALUES (#dept_name,#jax_dept_id)
ELSE
UPDATE afm.[jax_dept]
SET dept_name = #dept_name
WHERE jax_dept_id = #jax_dept_id
END
I created the schema for the stored procedure using consume adapter service. Used them in the mapping and the orchestration. Though I was not able to use the lopping functoid in the mapping
So removed the lopping and deployed the application. And tried to run and it ran without any error but just insert the first record from the oracle view in to the SQL Server database leaving all the other records. How can this be approached so the entire set of records from the oracle is inserted/updated in to SQL Server database.

Here I converted the separate update and insert into one merge statement:
Create PROCEDURE [dbo].[uspInsertorUpdateDepartment]
#dept_name varchar(64),
#jax_dept_id char(32)
AS
BEGIN
SET NOCOUNT ON;
merge afm.[jax_dept] as target
using (select #dept_name as dept_name, #jax_dept_id as jax_dept_id) as source
on source.jax_dept_id = target.jax_dept_id
when matched then
update target
SET dept_name = #dept_name
when not matched then
insert (dept_name, jax_dept_id)
values (#dept_name,#jax_dept_id)
;
END

Use table type as a parameter for the SP, instead of passing individually. We can
use looping functoid if we use User Defined Table value as a parameter.
CREATE TYPE dbo.SampleType AS TABLE
(
dept_name varchar(64) not null,
jax_dept_id char(32) not null
)
---
Create PROCEDURE [dbo].[uspInsertorUpdateDepartment]
#TVP dbo.SampleType READONLY
AS
BEGIN
SET NOCOUNT ON;
--your insert or update query
For more infor on how to use table value parameter check out this link:-
https://learn.microsoft.com/en-us/sql/relational-databases/tables/use-table-valued-parameters-database-engine

Related

Copy Trigger stops row being inserted

I am trying to create a trigger that copies newly inserted data from one table and inserts it into another table in a linked server.
However, when the trigger is created it stops the data appearing in the original table until the trigger is deleted and also does not even copy it over to the other table in the linked server either.
Here is my trigger
GO /****** Object: Trigger [dbo].[CopyTMSINFO] Script Date: 12/07/2022 12:53:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[CopyTMSINFO]
ON [dbo].[d_iface_att]
After INSERT
AS DECLARE #EmpID nvarchar(MAX),
#datetime datetime
SELECT #EmpID = ins.emp_id FROM INSERTED ins;
SELECT #datetime = ins.date_and_time FROM INSERTED ins;
INSERT INTO [MAL-HQ-SQL01].[MallaghanApp].[dbo].[EmployeeClockIn] (Id,Employee,TASDateTimeStart,TMSDateTime,JobType)
VALUES ( NEWID(),#EmpID,0,#datetime, 'TMS')
Any help would be greatly appreciated as i dont know much about this stuff and i am really confused.
There are two issues with your trigger:
You need to use SET NOCOUNT ON to prevent the "rows done" messing up exepcted resultsets in some client drivers.
You need to take into account multiple (or zero) rows in the inserted table.
CREATE OR ALTER TRIGGER [dbo].[CopyTMSINFO]
ON [dbo].[d_iface_att]
AFTER INSERT
AS
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM inserted)
RETURN;
INSERT INTO [MAL-HQ-SQL01].MallaghanApp.dbo.EmployeeClockIn
(Id, Employee, TASDateTimeStart, TMSDateTime, JobType)
SELECT
NEWID(),
ins.emp_id,
0,
ins.date_and_time,
'TMS'
FROM inserted ins;
However, inserting into a linked server using a trigger is very bad form anyway. What happens if the remote server is offline?
You should instead use other replication methods, such as the remote server pulling data from this server using an Agent Job.

SQL Server stored procedure does not execute command when invoked from another server/framework but works locally

I have created a SQL Server stored procedure which contains insert and update statements and log table. When I execute the stored procedure locally using
EXEC stored_procedure_name param1
it works perfectly fine and logs entry is inserted into the log table; but when the same stored procedure is called from another server using the same SQL Server user, the stored procedure is called and correct output/response is going to calling server but insert and update statements are not executed and no logs are inserted.
Again, when I call the stored procedure locally, everything works. When I checked the entries in log table (with Id column as identity(1,1)), there are 2 entries with id 1 and 3.
I think entry with Id = 2 is inserted and then rollback as it called from another server.
I don't understand the different behavior. Please help.
Thanks in advance
ALTER PROCEDURE [dbo].[temp_procedure]
(#aid VARCHAR(MAX))
AS
BEGIN
SET NOCOUNT ON;
DECLARE #RETURN_CODE INT = -2;
DECLARE #RETURN_MESSAGE VARCHAR(MAX) = 'ENTITY NOT FOUND';
-- Check IF exist and Update
IF EXISTS (SELECT 1 FROM temp WHERE c = #aid)
BEGIN
UPDATE temp
SET a = 0, b = 0,
WHERE c = #aid;
SET #RETURN_CODE = 0;
SET #RETURN_MESSAGE = 'SUCCESS';
END
-- Log action and result in logging table for particular a_id
-- also has id column as identity
INSERT INTO [dbo].[Logs] ([A_Id], [Created_Date], [Return_Code], [Return_Message])
VALUES (#aid, GETDATE(), #RETURN_CODE, #RETURN_MESSAGE)
SELECT #RETURN_CODE AS 'RETURN_CODE', #RETURN_MESSAGE AS 'RETURN_MESSAGE';
END

Insert stored procedure data in a temp table in SQL Server

I am trying to insert the data of a stored procedure into a temp table like below
CREATE TABLE #CustomTable3HTML
(
ItemId varchar(30),
ItemId1 varchar(30)
)
INSERT INTO #CustomTable3HTML
EXEC SalesDeals.dbo.prGetDealProposalDetail 17100102, 1
but I am getting this error
Msg 8164, Level 16, State 1, Procedure prGetDealProposalDetail, Line 138 [Batch Start Line 1]
An INSERT EXEC statement cannot be nested.
I figured this is because the stored procedure already has an insert into clause defined and I found out that it can be used only once in the calling chain.
So I started looking for other options and found out about OpenRowSet which I am using as below
SELECT *
INTO #CustomTable3HTML
FROM OPENROWSET('SQLOLEDB','Server=Demo\Demo;Trusted_Connection=Yes;Database=SalesDeals',
'SET NOCOUNT ON;SET FMTONLY OFF;EXEC SalesDeals.dbo.prGetDealProposalDetail 17100102,1')
I am getting an error when I run this SQL command
Access to the remote server is denied because no login-mapping exists.
It works fine when I use a higher level account like sysadmin but fails with the other account which is a normal db owner on the database where I am running this SQL.
There is work around of this. It's not beautiful, but it will work.
In our outer query define a table:
CREATE TABLE #CustomTable3HTML
(
ItemId varchar(30),
ItemId1 varchar(30)
)
Change the procedure adding the following code at the end:
IF OBJECT_ID('tempdb..#CustomTable3HTML')
BEGIN
INSERT INTO #CustomTable3HTML
SELECT ....
END
ELSE
BEGIN
SELECT ....
END
After executing the stored procedure you will have the data in table.

How to Update or Insert a record using SQL Merge

I have a windows forms application that needs to edit an existing record if it already exists and create it if it does not. I'm using SQL Server 2008 R2. My application reads data from various tables which includes an ID field for the output table if a record already exists.
The ID field is blank if a new record is being created. The ID field is the primary key and an Identity (auto increment) field for the destination table.
I have created a stored procedure using MERGE that I hope will create a new record or update the existing one. The update part is working but I can't figure out what to do with the ID field when creating.
When doing an update I pass in an ID Parameter and the existing record is located. Obviously if it is a new record I won't have an ID yet but I can't then leave that Parameter out or I get an unassigned variable error as you would expect.
Here is my stored procedure. Am I just barking up the wrong tree here
somewhere?
Should I just create two stored procedures and call Update if I have and ID and Call Create if I don't have and ID?
Thanks for any assistance.
USE [Insurance]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CreateModifyValuation]
-- Add the parameters for the stored procedure here
#ValuationID int,
#OwnersCorporationID int,
#ValDate datetime,
#ValuerID int,
#Amount money,
#Printed bit,
#Approved bit,
#Notes varchar(max),
#MultiplierValue money,
#MultiplierClass char(10),
#Adjustment money,
#SubmittedDate datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
Merge Valuation as Target
USING (Select
#ValuationID,
#OwnersCorporationID,
#ValDate,
#ValuerID,
#Amount,
#Printed,
#Approved,
#Notes,
#MultiplierValue,
#MultiplierClass,
#Adjustment,
#SubmittedDate
)
As Source(
ValuationID,
OwnersCorporationID,
ValDate,
ValuerID,
Amount,
Printed,
Approved,
Notes,
MultiplierValue,
MultiplierClass,
Adjustment,
SubmittedDate
)
ON Source.ValuationID = Target.ValuationID
WHEN MATCHED THEN
UPDATE SET
Target.OwnersCorporationID = Source.OwnersCorporationID,
Target.ValDate = Source.ValDate,
Target.ValuerID = Source.ValuerID,
Target.Amount = Source.Amount,
Target.Printed = Source.Printed,
Target.Approved = Source.Approved,
Target.Notes = Source.Notes,
Target.MultiplierValue = Source.MultiplierValue,
Target.MultiplierClass = Source.MultiplierClass,
Target.Adjustment = Source.Adjustment,
Target.SubmittedDate = Source.SubmittedDate
WHEN NOT MATCHED BY Target THEN
INSERT (
OwnerscorporationID,
ValDate,
ValuerID,
Amount,
Printed,
Approved,
Notes,
MultiplierValue,
MultiplierClass,
Adjustment,
SubmittedDate
)
VALUES (
Source.OwnersCorporationID,
Source.ValDate,
Source.ValuerID,
Source.Amount,
Source.Printed,
Source.Approved,
Source.Notes,
Source.MultiplierValue,
Source.MultiplierClass,
Source.Adjustment,
Source.SubmittedDate
);
END
I feel like I cheated but it's only one line so how bad can it be :)
In My SQL I added this line before the "SET NOCOUNT ON;"
(Funny if I put it after SET NOCOUNT ON I get a syntax error)
if (#ValuationID = 0) set #ValuationID = null
Then in my C# code I set the ID to 0 for a new record and it seems to work after a couple of tests. There may be a better way to do this but like most things in life you stop looking once it works.
Thanks again to those who commented.
David

How to execute sql scripts from a staging table in sql stored procedure

What are the best approaches to the below scenario?
In my C# program, I have some sql commands such as UPDATE, INSERT, DELETE. I could execute them in my C# program (which works fine) but I need to execute these sql commands when one of the stored procedure comes to the last line. So I am planning to store the sql commands in some staging table in the same database and then I would like to open this table within the stored procedure and execute one by one.
What is the best approach in terms of opening a table within stored procedure and then traversing through the table based on some condition (like select * from TempStagingTable where customerId = '1000'). If it returns 10 records, I would like to loop them and execute the sql command stored in a column named "CustomSqlScript"
PS: I am using SQL 2008 R2.
Well, you can select the data from table A initially, and instead of using cursor you can use while loop(as it will increase your performance compared to cursor) and then you can execute your predefined SQL statement from table B
Please find below sql scripts to do the same
Please note: I have not made use of any relation,This is just a plain example
CREATE TABLE test1(
customSqlScripts VARCHAR(100)
)
CREATE TABLE test2(
customer_Id INT PRIMARY KEY ,
first_Name VARCHAR(100),
last_name VARCHAR(100)
)
INSERT INTO test1 VALUES('Select first_Name from test2 where customer_Id=')
INSERT INTO test2 VALUES('1','Rohit','Tiwari')
DECLARE #Count INT
DECLARE #iCount INT=0
DECLARE #dummysql VARCHAR(100)
SELECT #Count= Count(*)
FROM test2
WHERE last_name='Tiwari'
WHILE(#icount<#count)
BEGIN
SELECT #dummysql =customSqlScripts
FROM test1
SET #dummysql=#dummysql+'1'
EXEC (#dummysql)
SET #icount=#icount+1
END

Resources