Replacement for "select * into" in sql azure? - azure

I need a way to generically take a table and copy its data into a new table--basically the same thing that SELECT * INTO does in regular SQL Server. Is there a way to do this in SQL Azure? I only have the existing and new table names at this point.

I encountered the same problem and the author's answer is not very detailed, so I will give some more information, on how i solved it.
I needed to duplicate tables that start with a given prefix ('from_') into new tables with prefix ('to_').
Generate CREATE Statement
I use this query (found on stackoverflow) to generate all CREATE statements, for every table that starts with 'from_' prefix.
select 'create table [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END as query
OBJECTPROPERTY(object_id(TABLE_NAME), 'TableHasIdentity') as tablehasidentity
from sysobjects so
cross apply
(SELECT
' ['+column_name+'] ' +
data_type + case data_type
when 'sql_variant' then ''
when 'text' then ''
when 'ntext' then ''
when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')'
else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') end + ' ' +
case when exists (
select id from syscolumns
where object_name(id)=so.name
and name=column_name
and columnproperty(id,name,'IsIdentity') = 1
) then
'IDENTITY(' +
cast(ident_seed(so.name) as varchar) + ',' +
cast(ident_incr(so.name) as varchar) + ')'
else ''
end + ' ' +
(case when IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' +
case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', '
from information_schema.columns where table_name = so.name
order by ordinal_position
FOR XML PATH('')) o (list)
left join
information_schema.table_constraints tc
on tc.Table_name = so.Name
AND tc.Constraint_Type = 'PRIMARY KEY'
cross apply
(select '[' + Column_Name + '], '
FROM information_schema.key_column_usage kcu
WHERE kcu.Constraint_Name = tc.Constraint_Name
ORDER BY
ORDINAL_POSITION
FOR XML PATH('')) j (list)
where xtype = 'U'
AND name NOT IN ('dtproperties') AND name like 'from_%'
This query results in a set of values:
['query'] = create table [from_users_roles] ( [uid] int NOT NULL DEFAULT ((0)), [rid] int NOT NULL DEFAULT ((0)), )ALTER TABLE from_users_roles ADD CONSTRAINT from_users_roles_pkey PRIMARY KEY ([uid], [rid])
['tablehasidentity'] = 1 or 0
Now replace the prefixes in the query 'from_' with 'to_' and the CREATE Statement is finished:
create table [to_users_roles] ( [uid] int NOT NULL DEFAULT ((0)), [rid] int NOT NULL DEFAULT ((0)), )ALTER TABLE to_users_roles ADD CONSTRAINT to_users_roles_pkey PRIMARY KEY ([uid], [rid]);
Create INSERT Statement
When you want to insert data from one table to another, you have to distinguish between two cases:
TablehasIdentity == 0
INSERT INTO to_users_roles SELECT * FROM from_users_roles
TablehasIdentity == 1
This case is a bit more complex. The statement requires a column list and IDENTITY_INSERT switched on.
DECLARE #Query nvarchar(4000)
DECLARE #columnlist nvarchar(4000)
// Result of this query e.g.: "[cid], [pid], [nid], [uid], [subject]"
SET #columnlist = (SELECT SUBSTRING((SELECT ', ' + QUOTENAME(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'from_users_roles' ORDER BY ORDINAL_POSITION FOR XML path('')), 3, 200000))
SET #query ='SET IDENTITY_INSERT to_users_roles ON; INSERT INTO to_users_roles (' + #columnlist + ') SELECT ' + #columnlist + ' FROM from_users_roles; SET IDENTITY_INSERT to_users_roles OFF'
exec sp_executesql #query;
This worked out for me pretty well.

The latest version of Azure SQL DB, now in Preview, supports the SELECT INTO syntax and no longer requires a clustered index. For a detailed description of its features, and how to use it, see http://azure.microsoft.com/en-us/documentation/articles/sql-database-preview-whats-new/

After doing more research, it looks like there is no simple way to do this. You basically have to read the table's schema information and create the new table based on that.

Select into is now supported SQL DB V12. Just upgrade your server and start using the syntax.

I found a clever trick on this blog
Instead of using "select into" use "insert select".
First you have to create the destination table. To do this, right click on the source table in SQL Management Studio, and choose "Script Table as" -> "Create To" -> "New Query Window".
Then, change the name of the table in the query, and execute the query. Below is an example where I have added today's date to the new table, calling it "Entities_2015_08_24" (the old table was called "Entities"):
CREATE TABLE [dbo].[Entities_2015_08_24](
[Url] [nvarchar](max) NULL,
[ClientID] [nvarchar](max) NULL
)
Then, do a "insert select" from the old table (Entities) into the new table (Entities_2015_08_24):
INSERT INTO [dbo].[Entities_2015_08_24]
([Url]
,[ClientID]
)
SELECT
[Url]
,[ClientID]
FROM [dbo].[Entities]

Q: Did you try it?
Q: Did you look at the SQL Azure documentation
ADDENDUM
AFAIK, you cannot use select into syntax to "clone" a table in Azure SQL. Because Azure requires a clustered index, and select into has no provision for defining one.
Details, and a potential workaround, are here:
http://blogs.msdn.com/b/windowsazure/archive/2010/05/04/select-into-with-sql-azure.aspx

Related

MssqlRow to json string without knowing structure and data type on compile time [duplicate]

Using PostgreSQL I can have multiple rows of json objects.
select (select ROW_TO_JSON(_) from (select c.name, c.age) as _) as jsonresult from employee as c
This gives me this result:
{"age":65,"name":"NAME"}
{"age":21,"name":"SURNAME"}
But in SqlServer when I use the FOR JSON AUTO clause it gives me an array of json objects instead of multiple rows.
select c.name, c.age from customer c FOR JSON AUTO
[{"age":65,"name":"NAME"},{"age":21,"name":"SURNAME"}]
How to get the same result format in SqlServer ?
By constructing separate JSON in each individual row:
SELECT (SELECT [age], [name] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
FROM customer
There is an alternative form that doesn't require you to know the table structure (but likely has worse performance because it may generate a large intermediate JSON):
SELECT [value] FROM OPENJSON(
(SELECT * FROM customer FOR JSON PATH)
)
no structure better performance
SELECT c.id, jdata.*
FROM customer c
cross apply
(SELECT * FROM customer jc where jc.id = c.id FOR JSON PATH , WITHOUT_ARRAY_WRAPPER) jdata (jdata)
Same as Barak Yellin but more lazy:
1-Create this proc
CREATE PROC PRC_SELECT_JSON(#TBL VARCHAR(100), #COLS VARCHAR(1000)='D.*') AS BEGIN
EXEC('
SELECT X.O FROM ' + #TBL + ' D
CROSS APPLY (
SELECT ' + #COLS + '
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) X (O)
')
END
2-Can use either all columns or specific columns:
CREATE TABLE #TEST ( X INT, Y VARCHAR(10), Z DATE )
INSERT #TEST VALUES (123, 'TEST1', GETDATE())
INSERT #TEST VALUES (124, 'TEST2', GETDATE())
EXEC PRC_SELECT_JSON #TEST
EXEC PRC_SELECT_JSON #TEST, 'X, Y'
If you're using PHP add SET NOCOUNT ON; in the first row (why?).

Assign Column Name for Simple Coalesce Statement

While attempting to create a list of all ID's made since _____ I am able to get the results I want from the following:
DECLARE #BoID varchar(max)
SELECT #BoID = COALESCE(#BoID + ', ', '') +
CAST(ApplicationID AS varchar(10))
FROM BoList as "ID"
WHERE CreatedDate > '2017-07-01 18:14:09.210'
However, I am having issues with establishing a column name for the above statement. Where does the as "ID" need to be located at in order to give the above result a column name of "ID"?
As the query stands now, you are giving the table BoList an alias of "ID" instead of the column. Since you are selecting the value into a variable there is no output. You can do it like this...
SELECT COALESCE(#BoID + ', ', '') +
CAST(ApplicationID AS varchar(10)) as "ID"
FROM BoList
WHERE CreatedDate > '2017-07-01 18:14:09.210'
Or if you really do need to stash the value in a variable to return later as part of another query...
DECLARE #BoID varchar(max)
SELECT #BoID = COALESCE(#BoID + ', ', '') +
CAST(ApplicationID AS varchar(10))
FROM BoList
WHERE CreatedDate > '2017-07-01 18:14:09.210'
SELECT #BoID AS "ID", other columns... FROM whatever

Insert the data into the remote table from # temp table in the stored procedure

I have a stored procedure in AZURE SQL database.In that there is a requirement to insert the records into the remote table from #temp table.
As xxxx_table is in the remote database used sp_execute_remote.
below is the scenario:
Create Procedure SP1 parameter1, Parameter2
As
select Distinct B.column1, B.Column2
into #A
from (Query1
Union
Query2) B
if (select count(1) from #A) > 0
Begin
Exec sp_execute_remote #data_source_name = N'Remotedatabase',
#stmt = N'INSERT INTO [dbo].[xxxx_table]
SELECT DISTINCT
'xxx' AS 'column1',
'xxx as 'Column2',
'xxx' AS 'Column3',
'xxx' AS 'Column4',
'xxx' AS Column4
FROM #A A INNER JOIN table1 on A.Column1 = Table1.Column2'
End
)
Getting the syntax error as below:
Incorrect syntax near 'xxx'.
Where am i going wrong? or let me know if there is another way to achieve this.
If you need to dynamically build a string in SQL single-quote the whole sentence, or use 'some text' + 'another text' to concat sentences. If you must add single quote use a double single quote ''
Example:
DECLARE #param1 int;
DECLARE #param1 VARCHAR(10);
SET #param1 = 10;
SET #param2 = 'CCDOS87'
#Stmt = 'SELECT Field1 FROM TableName WHERE Field1 = '
+ CAST(#param1 AS VARCHAR(100))
+ ' AND Field1 = '''
+ param2
+ ''''; <- This is a single '
#stmt = N'INSERT INTO [dbo].[Error_table]
SELECT DISTINCT
xxx AS column1,
xxx as Column2,
xxx AS Column3,
xxx AS Column4,
xxx AS Environment
FROM #A A INNER JOIN table1 on A.Column1 = Table1.Column2'
update
If your tables are in different databases but in the same server use:
INSERT INTO SERVER.SCHEMA.TABLE_NAME
SELECT Something
FROM SERVER.SCHEMA.TABLE_NAME

SSIS Import from excel with column names in first column

I have an excel workbook which has numerous worksheets in it.
Each worksheet has data which represents a schema.
The problem is that the data is not laid out with a header row, but instead it has a header "column". Also data is only contained in the 7th to 13th row of the sheet i.e.:
Field Name | Swap ID | Allocation ID | Description | Broker ID ...
Field Type | Alphanumeric| Alphanumeric | Alphanumeric| Alphanumeric ...
Field Length| char(40) | char(40) | char(100) | char(50) ....
...
How would I go about importing one of these worksheets into a database table with the following structure?
Field Name | Field Type | Field Length | ...
NOTE: My problem is not just skipping down past the row content, but how to "pivot" the data in such a way that my data which is laid out by columns is instead laid out by rows.
Edit: Thanks to praveen's answer I am able to handle the requirement for using a specific range of cell's using the Select * from [Sheet$A7:AZ13] syntax, but the main problem of importing data which is essentially turned on its side still exists.
Try this :-
Step 1: While creating Excel Connection Manager select the option First Rows as Column name
Step 2: In excel source use SQL Command for Data access mode and write the query to skip the initial rows
SELECT * FROM [Sheet1$A7:B]
There can be many things that can potentially change between one Excel sheet and another. So, use this solution only as startign point.
If you have any question, please let us know. (-; Disclaimer over ;-)
I created an Excel file that looks like this:
Field Name | Swap ID | Allocation ID | Description | Broker ID
Field Type | Alphanumeric| Alphanumeric | Alphanumeric| Alphanumeric
Field Length| char(40) | char(40) | char(100) | char(50)
Load your Excel file into a staging table (STG_Sheet1).
CREATE TABLE [dbo].[STG_Sheet1]
(
[F1] varchar NULL
, [F2] varchar NULL
, [F3] varchar NULL
, [F4] varchar NULL
, [F5] varchar NULL
) ON [PRIMARY]
Now, Create a new SSIS package.
2.1 Create the following variables:
2.1.1 oFieldList; Data type: Object
2.1.2 sColumn; Data type: String, Value: F2
2.1.3 sSql; Data type: String, Value: "SELECT " + #[User::sColumn] + " AS COL FROM [dbo].[STG_Sheet1]"
2.1.4 sSQLInsert; Data type: String
2.1.5 sValues; Data type: String
2.2 Place a Script Task.
2.2.1 Result Set: Full result set
2.2.2 SQL Statement:
SELECT sac.name as ColumnName FROM sys.all_columns sac
INNER JOIN sys.all_objects sao ON sao.object_id = sac.object_id
WHERE sao.name = 'STG_Sheet1' AND sac.name <> 'F1'
2.2.3 Result Set: Result Name: 0; Variable Name: User::oFieldList
2.3 Place a ForEach Loop Container
2.3.1 Enumerator: Foreach ADO Enumerator
2.3.2 ADO object source variable: User::oFieldList
2.3.3 Variable Mappings: User::sColumn: 0
Now, inside the ForEach Loop Container
2.4 Place a DFT
2.4.1 Place an OLE DB Source
2.4.1.1 Data access mode: SQL Command from variable
2.4.1.2 Variable name: sSQL
2.4.1.3 Columns: COL
2.4.2 Place a Script component as Transformation
2.4.2.1 Input Columns: COL : ReadOnly
2.4.2.2 Script: ReadWrite Variables:User::sValues
2.4.2.3 Edit Script : Code below
public class ScriptMain : UserComponent
{
string colValue = string.Empty;
public override void PreExecute()
{
base.PreExecute();
}
public override void PostExecute()
{
base.PostExecute();
string x = Variables.sValues;
int iFirstCommaAt = colValue.IndexOf (',');
colValue = colValue.Substring(iFirstCommaAt + 1);
Variables.sValues = colValue;
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string x = Row.COL;
colValue = string.Format("{0},'{1}'", colValue, x);
}
}
2.5 Place a Script Task:
2.5.1 ReadOnlyVariables: User::sValues
2.5.2 ReadWriteVariables: User::sSQLInsert
2.5.3 Edit Script: Code below
public void Main()
{
string s = "INSERT INTO dbo.SHEET1 ([Field Name], [Field Type], [Field Length]) VALUES ";
string sValue = Dts.Variables["User::sValues"].Value.ToString();
string sSQLInsert = string.Empty;
Dts.Variables["User::sSQLInsert"].Value = string.Format("{0} ({1})", s, sValue);
Dts.TaskResult = (int)ScriptResults.Success;
}
2.6 Place an Execute SQL Task
2.6.1 SQLSourceTyoe: Variable
2.6.2 SourceVariable: User::sSQLInsert
You can also experiment with this:
(After you have loaded the Excel sheet into the staging table, run the following script from the SSMS:
SELECT * FROM [dbo].[STG_Sheet1]
SELECT * FROM [dbo].[Sheet1]
DECLARE #CETList2 varchar(300); DECLARE #CETList3 varchar(300);
DECLARE #CETList4 varchar(300); DECLARE #CETList5 varchar(300);
DECLARE #INSERT varchar(1000) DECLARE #EXEC_INSERT varchar(1000);
SET #INSERT = 'INSERT INTO dbo.SHEET1 ([Field Name], [Field Type],[Field Length]) VALUES';
SELECT
#CETList2 = COALESCE(#CETList2 + ',', '') + '''' + LTRIM(RTRIM(CAST(CETL.[F2] AS Varchar))) + ''''
, #CETList3 = COALESCE(#CETList3 + ',', '') + '''' + LTRIM(RTRIM(CAST(CETL.[F3] AS varchar))) + ''''
, #CETList4 = COALESCE(#CETList4 + ',', '') + '''' + LTRIM(RTRIM(CAST(CETL.[F4] AS varchar))) + ''''
, #CETList5 = COALESCE(#CETList5 + ',', '') + '''' + LTRIM(RTRIM(CAST(CETL.[F5] AS varchar))) + ''''
FROM [dbo].[STG_Sheet1] CETL
SET #EXEC_INSERT = #INSERT + '(' + #CETList2 + ')';
EXECUTE (#EXEC_INSERT)
SET #EXEC_INSERT = #INSERT + '(' + #CETList3 + ')';
EXECUTE (#EXEC_INSERT)
SET #EXEC_INSERT = #INSERT + '(' + #CETList4 + ')';
EXECUTE (#EXEC_INSERT)
SET #EXEC_INSERT = #INSERT + '(' + #CETList5 + ')';
EXECUTE (#EXEC_INSERT)
SELECT * FROM [dbo].[Sheet1]

According to a temporary table (Table Schema and data)

According to a temporary table (Table Schema and data), how can i create a physical table and insert returned records to it?
hi,
in the below sample code , i am retriving columns from the temp table using the case condition..
in the step 2 we are checking for any column has been selected from the case statement..
in the step 3 we are selecting only the columns which have been retrieved from the above case stmnt..
in the step 4 we are creating the physical table with the columns names which have selected above and then inserting into it..
atlast drop both the tables
i hope this would help you
step1:
DECLARE #dynsql NVARCHAR(MAX)
SELECT #dynsql =
CASE WHEN columnname1 >0 THEN ',columnname' ELSE '' END +
CASE WHEN columnname2 >0 THEN ',columnname2' ELSE '' END +
.
.
CASE WHEN columnnamen >0 THEN ',columnnamen ' ELSE '' END
FROM ##temptble
WHERE condition = cond;
step 2:
IF(LEN(#dynsql) > 0)
BEGIN
step 3:
SET #dynsql = STUFF(#dynsql,1,1,'SELECT machinename, ') + ' FROM ##temptble'
EXEC(#dynsql)
END
decalre f nvarchar(max)
step 4:
set #f = STUFF(#dyncreate,1,6,'create table ven_temp( descriptionname nvarchar(111),' ) + ' int )'
exec(#f)
insert into ven_temp
EXEC(#dynsql)

Resources