I have a stored procedure in SQL Server that contains 4 insert processes:
Process 1, Lookup data from Chief 1 and insert it to Archive table
Process 2, Lookup data from Chief 2 and insert it to Archive table
Process 3, Lookup data from Chief 3 and insert it to Archive table
Process 4, Lookup data from Chief 4 and insert it to Archive table
All processes work in the stored procedure, so the application only calls to run the one stored procedure.
When I execute using CodeIgniter (SQLSRV) with command:
EXEC getwage_bcmbs #date_start = '2020-04-28'
The process only works up to process #2. Then the result only 2 records in Archive table.
But, when I execute the command in SQL Server Management Studio, the processes normally run until process 4. Then the result are 4 records.
Please can anybody help me? What is the problem? Is it caused by some trouble in the stored procedure or inside SQLSRV?
PHP Version 7.2.18-1 + Ubuntu18.04.1 + deb.sury.org+1
SQL Server 2016
Solved
I currently need to add
SET NOCOUNT ON
to my Store Procedure.
In my SP, I make the process that insert to Temporary table and when continue to process 2, the temporary table will be deleted.
When the temporary table return 0 data to delete, then the SQL Server return message that handled by SQLSRV as a complete process messages. Then the process stop in the process 2.
May be that why my SP not run completely when i call it from SQLSRV. But normally run when i call it using SMSS or SQL Server Client programs
Thanks StackOverflow
Related
I know lots have already been written about what GO does and when to use it but I haven't seen anything which explains the following scenario.
We have been supplied with some stored procedures with an application to populate a set of static warehouse tables, but they were producing error messages. Each procedure has the following structure:
exec usp_CreateDWTable
insert into dbo.DWTable
Select [somefields]
from [SomeLiveTables]
The usp_CreateDWTable stored procedure consists of:
if exists (select * from sysobjects where id = object_id('dbo.DWTable') and sysstat & 0xf = 3)
drop table dbo.DWTable
CREATE TABLE dbo.DWTable(CONSTRAINT [field1] PRIMARY KEY (Alert_ID),[field2],,,)
Running as above returns the error message:
Msg 213, Level 16, State 1, Line 15
Column name or number of supplied values does not match table definition.
I have eventually worked out that adding GO between the EXEC and the INSERT fixes the issue but if sql process commands sequentially anyway what difference does this make? Now I know a CREATE TABLE batch has to be sent to the server before you can send an INSERT but I have read that sql can handle this scenario implicitly, is the fact that the CREATE TABLE is in a sp interfering with this?
Even if my above assumption above is correct, an additional source of confusion is that we have two instances of this database on the server and this error does not happen on the other database. The structures of both databases are virtually identical, although the data is different. Is there a setting within the database that is causing them to behave differently?
Thanks
The entire batch is compiled using the existing table definition when the table already exists. So when the batch includes drop/create/insert, the batch is validated against the existing schema before the new table is created and compilation fails when the existing/new table has a different number of columns.
When you execute the script as separate batches (GO command), the drop/create statements are executed first. Then the insert statement batch is then compiled and run using the new table definition.
I query my database from within a .NET application (time recoding). I send the Windows user name to the database and query it depending on this information.
I query a lot of different information with stored procedures, such as holiday, overtime etc. and send them back to the .NET application where I show this data in one form.
Let's say I need the information from SP1, 3 and 4 on Form1:
FORM1:
SP1
SP3
SP4
My problem:
I have a quite complicated table that I need for these stored procedures. At the moment I create this table in every of those stored procedures as temporary tables what is obviously quite time consuming.
What I have tried so far is creating a stored procedure that creates a temp table but this one is not accessable within my other stored procedures.
My question: I am looking for a way to create this table for Form1 once, so I can just access these table in the other stored procedures.
I'm using SQL Server 2014 Express.
If you create the temporary table outside of any stored procedure, it will be accessible within each. Assuming that the actual table definition isn't too complex (but populating it may be), this may be doable.
So you'd execute (effectively):
CREATE TABLE #T (A int not null, B varchar(17) not null)
EXEC PopulateTempTable
EXEC SP1
EXEC SP3
EXEC SP4
All on a single connection. PopulateTempTable may or may not be required, depending on how complex the population of the table is and whether you want that to be performed by your calling code or the database.
You cannot create the temp table inside of a stored procedure since temp tables are automatically dropped when the scope of a stored procedure is exited.
Alternatively, you may want to simulate "session-global" temp tables, as I suggest in this answer1.
The risk with using a global temp table is that it is truly global - all sessions see and interact with the data in the same table. You have to be very careful in such circumstances if it's at all possible that two sessions will attempt to use it at the same time; You generally need some means to filter the data in the table so that each session only works with its own data.
1Probably enhanced these days by also adding a Logon Trigger to clear down the old contents of the table whenever a new connection is established.
You have to create global temp table
CREATE TABLE ##TEMP1
(
Name varchar(50)
)
I have sometimes a problem when running a script. I have the probelm when using an application (that I didn't write and therefore cannot debug) that launches the scripts. This app isn't returning the full error from SQL Server, but just the error description, so I don't know exactly where th error comes.
I have the error only using this tool (it is a tool that sends the queries directly to SQL Server, using a DAC component), if I run the query manuallyin management studio I don't have the error. (This error moreover occurs only on a particular database).
My query is something like:
SELECT * INTO #TEMP_TABLE
FROM ANOTHER_TABLE
GO
--some other commands here
GO
INSERT INTO SOME_OTHER_TABLE(FIELD1,FIELD2)
SELECT FIELDA, FIELDB
FROM #TEMP_TABLE
GO
DROP TABLE #TEMP_TABLE
GO
The error I get is #TEMP_TABLE is not a valid object
So somehow i suspect that the DROP statement is executed before the INSERT statement.
But AFAIK when a GO is there the next statement is not executed until the previous has been completed.
Now I suspoect that this is not true with temp tables... Or do you have another ideas?
Your problem is most likely caused by either an end of session prior to the DROP TABLE causing SQL Server to automatically drop the table or the DROP TABLE is being executed in a different session than the other code (that created and used the temporary table) causing the table not to be visible.
I am assuming that stored procedures are not involved here, because it looks like you are just executing batches, since local temporary tables are also dropped when a stored proc is exited.
There is a good description of local temporary table behavior in this article on Temporary Tables in SQL Server:
You get housekeeping with Local Temporary tables; they are
automatically dropped when they go out of scope, unless explicitly
dropped by using DROP TABLE. Their scope is more generous than a table
Variable so you don't have problems referencing them within batches or
in dynamic SQL. Local temporary tables are dropped automatically at
the end of the current session or procedure. Dropping it at the end of
the procedure that created it can cause head-scratching: a local
temporary table that is created within a stored procedure or session
is dropped when it is finished so it cannot be referenced by the
process that called the stored procedure that created the table. It
can, however, be referenced by any nested stored procedures executed
by the stored procedure that created the table. If the nested
procedure references a temporary table and two temporary tables with
the same name exist at that time, which table is the query is resolved
against?
I would start up SQL Profiler and verify if your tool uses one connection to execute all batches, or if it disconnects/reconnects. Also it could be using a connection pool.
Anyway, executing SQL batches from a file is so simple that you might develop your own tool very quickly and be better off.
I'm trying to setup a scheduled job that with one step that would insert the results from a sproc into a table.
INSERT INTO results_table EXEC sproc
The job executes and reports a success. Yet nothing gets inserted into a table. When I execute the same script from the SSMS the results are inserted. What might cause the problem?
** EDIT the job is owned by sa and the step is executed as dbo. All the runs in the history are reported as finished successfully. I've tried changing the step to
INSERT INTO results_table(field_names) (SELECT values FROM table GROUP BY column_name)
and it behaves in a similar way
** EDIT the problem only occurs when I select from the master database. Selecting from other tables works fine.
Check if you are inserting in the Master database or the the database that you want to insert. Or call the SP with database instanse inside the job step
Insert Into Results_Table
EXEC <DBNAME>.<SchemaName>.<ProcedureName>
Have you tried inserting the results of the stored procedure into a temp table first then inserting them into your results_table? I would suggest that as well as this article which reviews this concept in-depth: http://www.sommarskog.se/share_data.html
The problem was that in the scheduled job the stored procedure was executed not in the context of master database.
I've tried every avenue on every damn forum suggested, but to no avail!
Need to send results of SQLPERF(logspace), that have been stored in a table, via sp_send_dbmail to recipient.
Step 2 of job is where failure occurs. Please help!
EXEC msdb.dbo.sp_send_dbmail
#profile_name= 'MyDBA',
#recipients= 'Mack#mydba.co.za',
#subject='Log Warning',
#query='SELECT * from #TempForLogSpace WHERE LogSpaceUsed >80
You can't query from a temp table using database mail. The session that you used to create the temp table (step 1 of your job I assume) has been closed and a new session started when step 2 started. Because the session has been closed the table has been dropped (even if the table hasn't been dropped because it's a new session you don't have access to the other sessions temp table).
Either create a physical table and use that (either in the tempdb database or your database) or put the code which creates the output in the #query with the select * from #TempForLogSpace at the end (a stored procedure will be much easier to deal with in this case).
I know this thread is a bit old, but in case someone stumbles on this, the problem is like mrdenny said that sp_send_dbmail stored procedure runs in it's own session, however you can get around this by using a global temporary table instead (prefix the table with two pound signs (##)).
Just use a global temp table like ##temp_table. This table will be accessible by all sessions and will remain in database until all sessions that referred it have been closed.
Local and global temporary tables in SQL Server