Couldn't create temp table from select query if result empty - sql

I want to crate a temp table from select query (My table has many columns, therefore I don't want to create the temp table manually)
I use the following query:
SELECT * INTO #TempTable
FROM MyTable
WHERE ...
If this query return empty rows, it won't create #TempTable. Hence, I cannot use this #TempTable for the next queries.
Is there a way to resolve this?

If the query SELECT * FROM MyTable WHERE ... in your code you posted:
SELECT *
INTO TempTable
FROM MyTable WHERE ...
returned no rows, it will create an empty TempTable, but it won't fill any data in it if there is no rows matched the WHERE clause. But it should create the table TempTable at least with the same structure as the MyTable and it will be empty.
For example this:
SELECT * INTO TempTable FROM MyTable WHERE 1 <> 1;
Will always create an empty table TempTable with the same structure as MyTable since the predicate 1 <> 1 is always false.
However you can declare it like so:
DECLARE #Temp TABLE(Field1 int, ...);

This is because you are dynamically creating and populating temporary table and not creating it explicitly.In such scenario, you must check the existence of the temp table in the beginning before you create one.
Try this:
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable
END
SELECT * INTO #TempTable FROM MyTable
Select * From #TempTable

your query
SELECT * INTO #TempTable
FROM MyTable
WHERE ...
will create an empty table if the select returns no rows

Related

how to see difference between 2 tables

I have 2 tables: 1 temp and the other one is my main table.
Each day I would update my temp table and I want to update my main table based on the changes I made from the temp table.
Example: The first temp table contains an id and name. Then I insert the value from temp into the main table. But when I made changes from my temp like insert another id and name, I want my main table to compare and only insert the unique id from the temp table.
As you said, it seems like you have a table object named as temp table. If this is the case then you may use after insert trigger on temp table to insert new inserted value in your main table.
CREATE TRIGGER AfterINSERTTrigger on [Temptable]
FOR INSERT
AS DECLARE #id INT,
#col1 VARCHAR(50),
.
.
SELECT #id = ins.id FROM INSERTED ins;
SELECT #col1 = ins.col1 FROM INSERTED ins;
.
.
INSERT INTO [MainTable](
[id]
,[col1]
.
.)
VALUES (#id,
#col1,
.
.
.
);
PRINT 'We Successfully Fired the AFTER INSERT Triggers in SQL Server.'
GO
Similarly you can update your table on update of record in temptable using update trigger. You may find this link on more info on trigger. LINK
OR
If you are creating temp table object to get the new inserted record then use simple not in or not exists clause to get the newly inserted record.
Using NOT IN
insert into maintable ( id, col1, ...)
select Id , col1, .... from temptable
where id not in (select id from maintable)
Using NOT EXISTS
insert into maintable ( id, col1, ... )
select id, col1, ... from temptable as temp
where not exists (select id from maintable as main where main.id=temp.id)
You can use NOT EXISTS as follows
INSERT into main_table(
id, name,
...
)
SELECT
id,name,
...
FROM temp_table t
WHERE
NOT EXISTS(
SELECT 1
FROM main_table m
WHERE m.id = t.id
)
Cheers!!

How to capture Output of SQL queries and

I have a Database and i want to execute few queries on it, and the results of the queries i.e. message, has to be comapared in my code if it is expected or not.
Please let me know how to capture the output of the SQL queries in any variable that can be used later in code for comparision.
Try the following Method :
Create a Table with the Same structure as of your Procedure output
Insert the Result of the SP Execution to the Table
Compare your Query result with the Table
Like this
CREATE PROCEDURE dbo.uSp_Temp
AS
SELECT
GETDATE() "MyDate"
DECLARE #T TABLE
(
MyDate DATE
)
INSERT INTO #T
EXEC uSp_Temp
SELECT
*
FROM #T
You can use Temp tables or temp variable to save the result set of a query.
Below is the sample for temp table
create table #temp (id int)
insert into #temp
select 1 as id
select * from #temp
Below is sample for Temp variable
declare #temp table (id int)
insert into #temp
select 1 as id
select * from #temp

Inserting data into a temporary table

After having created a temporary table and declaring the data types like so;
CREATE TABLE #TempTable(
ID int,
Date datetime,
Name char(20))
How do I then insert the relevant data which is already held on a physical table within the database?
INSERT INTO #TempTable (ID, Date, Name)
SELECT id, date, name
FROM physical_table
To insert all data from all columns, just use this:
SELECT * INTO #TempTable
FROM OriginalTable
Don't forget to DROP the temporary table after you have finished with it and before you try creating it again:
DROP TABLE #TempTable
SELECT ID , Date , Name into #temp from [TableName]
My way of Insert in SQL Server. Also I usually check if a temporary table exists.
IF OBJECT_ID('tempdb..#MyTable') IS NOT NULL DROP Table #MyTable
SELECT b.Val as 'bVals'
INTO #MyTable
FROM OtherTable as b
SELECT *
INTO #TempTable
FROM table
I have provided two approaches to solve the same issue,
Solution 1: This approach includes 2 steps, first create a temporary table with
specified data type, next insert the value from the existing data
table.
CREATE TABLE #TempStudent(tempID int, tempName varchar(MAX) )
INSERT INTO #TempStudent(tempID, tempName) SELECT id, studName FROM students where id =1
SELECT * FROM #TempStudent
Solution 2: This approach is simple, where you can directly insert the values to
temporary table, where automatically the system take care of creating
the temp table with the same data type of original table.
SELECT id, studName INTO #TempStudent FROM students where id =1
SELECT * FROM #TempStudent
After you create the temp table you would just do a normal INSERT INTO () SELECT FROM
INSERT INTO #TempTable (id, Date, Name)
SELECT t.id, t.Date, t.Name
FROM yourTable t
The right query:
drop table #tmp_table
select new_acc_no, count(new_acc_no) as count1
into #tmp_table
from table
where unit_id = '0007'
group by unit_id, new_acc_no
having count(new_acc_no) > 1
insert into #temptable (col1, col2, col3)
select col1, col2, col3 from othertable
Note that this is considered poor practice:
insert into #temptable
select col1, col2, col3 from othertable
If the definition of the temp table were to change, the code could fail at runtime.
Basic operation of Temporary table is given below, modify and use as per your requirements,
-- CREATE A TEMP TABLE
CREATE TABLE #MyTempEmployeeTable(tempUserID varchar(MAX), tempUserName varchar(MAX) )
-- INSERT VALUE INTO A TEMP TABLE
INSERT INTO #MyTempEmployeeTable(tempUserID,tempUserName) SELECT userid,username FROM users where userid =21
-- QUERY A TEMP TABLE [This will work only in same session/Instance, not in other user session instance]
SELECT * FROM #MyTempEmployeeTable
-- DELETE VALUE IN TEMP TABLE
DELETE FROM #MyTempEmployeeTable
-- DROP A TEMP TABLE
DROP TABLE #MyTempEmployeeTable
INSERT INTO #TempTable(ID, Date, Name)
SELECT OtherID, OtherDate, OtherName FROM PhysicalTable
insert #temptable
select idfield, datefield, namefield from yourrealtable
All the above mentioned answers will almost fullfill the purpose. However, You need to drop the temp table after all the operation on it. You can follow-
INSERT INTO #TempTable (ID, Date, Name)
SELECT id, date, name
FROM physical_table;
IF OBJECT_ID('tempdb.dbo.#TempTable') IS NOT NULL
DROP TABLE #TempTable;

MySQL: How to copy rows, but change a few fields?

I have a large number of rows that I would like to copy, but I need to change one field.
I can select the rows that I want to copy:
select * from Table where Event_ID = "120"
Now I want to copy all those rows and create new rows while setting the Event_ID to 155. How can I accomplish this?
INSERT INTO Table
( Event_ID
, col2
...
)
SELECT "155"
, col2
...
FROM Table WHERE Event_ID = "120"
Here, the col2, ... represent the remaining columns (the ones other than Event_ID) in your table.
This is a solution where you have many fields in your table and don't want to get a finger cramp from typing all the fields, just type the ones needed :)
How to copy some rows into the same table, with some fields having different values:
Create a temporary table with all the rows you want to copy
Update all the rows in the temporary table with the values you want
If you have an auto increment field, you should set it to NULL in the temporary table
Copy all the rows of the temporary table into your original table
Delete the temporary table
Your code:
CREATE table temporary_table AS SELECT * FROM original_table WHERE Event_ID="155";
UPDATE temporary_table SET Event_ID="120";
UPDATE temporary_table SET ID=NULL;
INSERT INTO original_table SELECT * FROM temporary_table;
DROP TABLE temporary_table;
General scenario code:
CREATE table temporary_table AS SELECT * FROM original_table WHERE <conditions>;
UPDATE temporary_table SET <fieldx>=<valuex>, <fieldy>=<valuey>, ...;
UPDATE temporary_table SET <auto_inc_field>=NULL;
INSERT INTO original_table SELECT * FROM temporary_table;
DROP TABLE temporary_table
Simplified/condensed code:
CREATE TEMPORARY TABLE temporary_table AS SELECT * FROM original_table WHERE <conditions>;
UPDATE temporary_table SET <auto_inc_field>=NULL, <fieldx>=<valuex>, <fieldy>=<valuey>, ...;
INSERT INTO original_table SELECT * FROM temporary_table;
As creation of the temporary table uses the TEMPORARY keyword it will be dropped automatically when the session finishes (as #ar34z suggested).
Let's say your table has two other columns: foo and bar
INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, "155"
FROM Table
WHERE Event_ID = "120"
If you have loads of columns in your table and don't want to type out each one you can do it using a temporary table, like;
SELECT *
INTO #Temp
FROM Table WHERE Event_ID = "120"
GO
UPDATE #TEMP
SET Column = "Changed"
GO
INSERT INTO Table
SELECT *
FROM #Temp
Hey how about to copy all fields, change one of them to the same value + something else.
INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, Event_ID+"155"
FROM Table
WHERE Event_ID = "120"
??????????
As long as Event_ID is Integer, do this:
INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, (Event_ID + 155)
FROM Table
WHERE Event_ID = "120"
Adding to the answer by #DaveTheBFG:
If you have an identity column ("Table_PK" in the below example), the INSERT line would fail, but you can do the following (SQL Server-specific, but the concept may apply to other databases):
SELECT *
INTO #Temp
FROM Table WHERE Event_ID = "120"
UPDATE #TEMP
SET Column = "Changed"
ALTER TABLE #TEMP DROP COLUMN Table_PK
EXEC sp_executesql N'INSERT INTO Table SELECT * FROM #Temp'
If you don't mind doing it in your code, its much easier to do. For example, in php you can do
function copyQuery($table, $row){
$queryColumns = $queryValues = '';
foreach ($row as $key => $value) {
$queryColumns .= $key.', ';
$queryValues .= "'$value', ";
}
$queryColumns = rtrim($queryColumns, ', ');
$queryValues = rtrim($queryValues, ', ');
return "INSERT INTO $table ($queryColumns) VALUES ($queryValues)";
}
$records = mysqli_query($connect, "SELECT * FROM Table WHERE Event_ID = 120");
while ($row = mysqli_fetch_assoc($records)) {
unset($row['id']);
$row['Event_ID'] = 155;
$query = copyQuery('Table', $row);
mysqli_query($connect, $query);
}
Using a function is optional. I made it because I needed to do it a few times. I used this option because now I can forget about it if the database columns change in the future.

How can I create two temporary tables with the same structure without write twice?

How can I create two temporary tables with the same structure without write twice?
Something like that:
DECLARE #TEST_TABLE1, #TEST_TABLE2 TABLE
(
FIELD1 INT,
FIELD2 INT
)
and NO:
DECLARE #TEST_TABLE1 TABLE
(
FIELD1 INT,
FIELD2 INT
)
DECLARE #TEST_TABLE2 TABLE
(
FIELD1 INT,
FIELD2 INT
)
These are not "temp tables", a temp table is CREATE TABLE #TempTable(x int)
to make this work for true table tables, try:
CREATE TABLE #TempTable(x int)
insert into #TempTable values(5) --test data to show no data copied to new table
select * into #tempTable2 from #TempTable where 1=2
select * from #TempTable
select * from #TempTable2
These are table vaiables (#tableVariable) and you have to declare each variable, there is no way around it.
The only very non-standard way I can think this may work is to just write to the sys.tables directly, but you would still have to do two inserts, but you are doing the tables at the same time.
That may not be what you want, but short of using a stored procedure, and making one call from your app, and two on the database I can't think of any other solution.
Create the first temp table, then select into a second temp table:
-- Create first temp table
CREATE TABLE #TEST_TABLE1
(
FIELD1 int
,FIELD2 int
)
-- Select into second temp table
SELECT *
INTO #TEST_TABLE2
FROM #TEST_TABLE1
-- Vet existence of both temp tables
SELECT * FROM #TEST_TABLE1
SELECT * FROM #TEST_TABLE2