I have 3 tables which have 180 columns, and I want to insert a record in all tables continuously using a stored procedure in SQL Server.
What is the best optimized way to do this?
Should I simply write an insert query in the stored procedure, or should I use functions for each insert query and after this I call function in my stored procedure?
Since functions in T-SQL cannot modify the database state, you cannot use them to insert data into a table. See the official MS documentation on function - scroll down to the section "Limitations and Restrictions" where it says:
User-defined functions cannot be used to perform actions that modify the database state.
Since you already have a stored procedure, you just need to write three separate INSERT statements (one for each table) inside that stored procedure to insert your data into the three tables by calling that stored procedure.
Does the 3 tables mentioned has the same number of column, as well as same column name?
If this is so, create a generic function with table name as input parameter would be more easy to use and maintain
Related
I am using DB2 and Oracle SQL Developer.
How to get the CREATE TABLE Statements from the existing tables?
There are too many tables and it will be a very lengthy process to do manually.
There is a special db2look utility for DDL extraction in Db2. You may refer to its options and their meaning at this link.
If you want SQL access to its capabilities, you may use the SYSPROC.DB2LK_GENERATE_DDL stored procedure supporting most of the utility's options. The routine has an output parameter getting "invocation number" int value after its call.
In case of a single table:
CALL SYSPROC.DB2LK_GENERATE_DDL ('-e -noview -t MY_SCHEMA.MY_TABLE', ?);
SELECT SQL_STMT
FROM SYSTOOLS.DB2LOOK_INFO_V
WHERE OP_TOKEN = <value_of_output_parameter_from_call_above>
ORDER BY OP_SEQUENCE;
In SQLDeveloper if you can see the table there's the initial Create Table Statement in the SQL Tab
You should do that for each table, this is a way to do it but I'm not sure it's fast enough for you.
I need to create a view, which begins with the following SQL:
IF OBJECT_ID('tempdb..#TempTable') Is Not null
Drop Table #TempTable
I am also rebuilding this #TempTable further on in the view, and then using data in the Temptable for the rest of the query - for better performance. See:
Reduce cost for Table Valued Function - XML Reader in query plan - how?
However, SSMS is telling me:
Incorrect syntax near the keyword 'IF'
Views or functions are not allowed on temporary tables.
Table names that begin with '#' denote temporary tables.
Is there any way to use the IF statement, drop the Temptable, and then use the rebuilt Temptable in the view?
ANSWER - I need to use a stored procedure, not a view.
A stored procedure is quite different from a view. A view is simply an encapsulated query.
However, a stored procedure cannot be used in a SELECT statement. You can only execute it using EXEC.
What you probably want is a user-defined function (UDF). UDFs return a table, so they can be referenced in the FROM clause of a query. Unlike a view, they can contain multiple statements and can have parameters.
As a note, there is no need to delete temporary tables in stored procedures or functions. If the temporary table is declared in the body of the code, then it is automatically deleted when the code is exited. However, you might want to use a table variable instead.
I'm currently working on a project where I insert or update a lot of data frequently to a remote database. The data volume is around 50 sets of data with 500-800 rows each, that goes into the same table.
Currently I have a stored procedure that I call for every row to insert or update (simplified for easier read):
ALTER PROCEDURE stat_memberstat_upsert
...
AS
BEGIN
UPDATE Memberstats ...
if(##ROWCOUNT = 0)
BEGIN
INSERT INTO Memberstats ...
END
END
This works, but as you can see it mounts to a lot of calls to the same stored procedure (worst case around 100,000 calls). I'm looking into User-defined table type, which sound like a good solution, because it decreases the calls to the database server, with a more bulk like structure. The problem is that when I look at the solutions, tutorials and documentations I find that no one mentions a way to do a insert/update routine with the table type; it's either insert or update.
Is there a way, when working with table types, to do a insert/update call?
Alternatively I have thought about two workaround solutions:
1: Using cursor
I could use a cursor to iterate through the table type value and call the stat_memberstat_upsert procedure above for each row. This will not prevent the many calls to the procedure, but since the calls are done from a local stored procedure the speed might increase.
How to do ForEach on user defined table type in SQL Server stored procedure? (answer "Why not use a cursor ???")
2: Pre validate data
Second solution is to retrieve the already inserted rows primary keys, validate them against the incoming data and sort them into 2 tables, where one is for inserts and the other one is for updates. Then execute both tables to the database. This means that I need to encapsulate this in a transaction so the table will not change during the time is take to validate and execute the insert and update.
Would any of these be a good solution?
Both the solution might slow down further.
You can simply have insert statements into a table
ALTER PROCEDURE stat_memberstat_upsert
...
AS
INSERT INTO Memberstats_temp ...
END
and have a batch process which will run at low traffic time to update/insert the Memberstats table from Memberstats_temp table after that truncating this temp table. This wouldn't be a solution if you need real time update to the table.
I have an old SQL script that is currently run by loading it into SQL Server Management studio and running it. I'd like to clean this up by turning it into a series of functions that are stored in the database itself.
The basic sequence of steps that the current code does is like this:
(Miles of SQL logic)
Create a temporary table
BULK INSERT from a CSV file into the temporary table
Massage the data
Merge the data into the "real" table
DROP the temporary table
(Miles of SQL logic)
I'd like to wrap steps 1-5 in a function, but I'm stuck at how to perform a BULK INSERT when you can't BULK INSERT into a table variable, and you're also not allowed to create temporary tables from within a function.
So what's the right way to fix this issue?
Thanks!
As already mentionned in the comment, the solution that differs the less to yours is doing that in a stored procedure rather than in a functoin, which is intended to modify the content of a table.
On a short term perspective, this should be clearly the easiest to implement for you but on a long term learnin SSIS could be a good investment.
I need to merge two tables in following way:
Target has one extra Column ID. This Id is coming FROM another Single Column Master Table.
While Inserting the Record in Merge Statement I need to INSERT a new row into mater table and use its id to insert into TARGET table.
I have created a Stored Procedure that Inserts and returns newly inserted ID. Now the Problem is inside SQL Merge, we can't call a stored Proc.
What could be the solution of this issue? Cant use Scalar functions as INSERT can't be performed in Functions.
DECLARE #temp INT
MERGE dbo.mytabletarget T
USING dbo.mytableSource S
ON T.refId=S.RefId
WHEN MATCHED THEN
UPDATE
SET T.col1=S.col1,
T.Col2=S.Col2
WHEN NOT MATCHED BY TARGET THEN
INSERT (Id,col1,col2)
VALUES({Here i need value from SP. SP simply Inserts a new Id into master table and Returns it},S.col1,S.col2);
GO
What could be the solution of this issue?
Do not use a stored procedure. Obvious, isn't it?
For a merge statement, you pretty much are stuck with doing the commands right there in the statement. Merge focuses on ETL loads and has advantages as well as limitations.
Basically, put the logic into the merge statement.
While Inserting the Record in Merge Statement I need to INSERT a new row into mater table
and use its id to insert into TARGET table.
Hm, lookup table maintenance?
The regular approach for that is ti make sure the lookup table is filled first (in a separate statement). ETL (and that is where merge comes from) often works along stages for that particular reason.
Sorry, I do not have a better solution either ;(