Dynamic SQL table creation - invalid object after execution? - sql

I am trying to create a table that dynamically pulls the starting IDENTITY ID based on a variable from another table. The SQL executes successfully but afterwards, I am unable to find my temporary table. The DBCC CHECKIDENT brings back Invalid object name '#address_temp'.
IF OBJECT_ID('tempdb.dbo.#address_temp', 'U') IS NOT NULL
DROP TABLE #address_temp
DECLARE #address_temp_ID VARCHAR(MAX)
SET #address_temp_ID = (SELECT MAX(ID) FROM [PRIMARYDB].[dbo].[ADDRESS])
DECLARE #SQLBULK VARCHAR(MAX)
SET #SQLBULK = 'CREATE TABLE #address_temp(
[ID] [int] IDENTITY(' + #address_temp_ID + ',1) NOT NULL,
[NAME] [varchar](128) NOT NULL,
[ADDRESS1] [varchar](128) NOT NULL,
[ADDRESS2] [varchar](128) NULL,
[CITY] [varchar](128) NULL,
[STATE_ID] [smallint] NULL,
[ZIP] [varchar](10) NOT NULL,
[COUNTY] [varchar](50) NULL,
[COUNTRY] [varchar](50) NULL
CREATE CLUSTERED INDEX pk_add ON #address_temp ([NAME])'
EXEC (#SQLBULK)
DBCC CHECKIDENT('#address_temp')

Table names that start with # are temporary tables and SQL Server treats them differently. First of all they are only available to the session that created them (this is not quite true since they you can find them in the temp name space but they have a unique system generated name)
In any case they won't persist so you don't need to drop them (that happens auto-magically) and you certainly can't look at them after your session ends.... they are gone.
Don't use a temp table, take out the # in the name. Things will suddenly start working.

Related

Insert a single Table into Multiple Databases

I am trying to insert a table into multiple databases.
I have figured out how to make it insert the single table into all of the Databases but I need it to exclude about 10 databases like the master, model, tempdb, msdb, then I have some others as well.
EXEC sp_msforeachdb
'
USE ?;
IF [?] NOT IN master, model, tempdb,
CREATE TABLE [?].[dbo].[FaceEnrollments](
[EmployeeNo] [varchar](10) NOT NULL,
[TIN] [varchar](20) NOT NULL,
[irFaceTemplate] [varchar](max) NULL,
[faceBitmap] [varchar](max) NULL,
[faceAttestationAccepted] [bit] NULL,
[EnrollmentDateTime] [datetime] NULL,
CONSTRAINT [PK_FaceEnrollments] PRIMARY KEY CLUSTERED
(
[EmployeeNo] ASC,
[TIN] ASC
)
);
';
This is what I got so far to add the table to all databases.
I have tried multiple things to exclude databases from this, but I cannot figure it out.
I was hoping someone could help me out. Please and Thank you!
you can adjust your dynamic query to this:
EXEC sp_msforeachdb
'
IF ''?'' NOT IN (''master'', ''model'', ''tempdb'')
CREATE TABLE ?.[dbo].[FaceEnrollments](
[EmployeeNo] [varchar](10) NOT NULL,
[TIN] [varchar](20) NOT NULL,
[irFaceTemplate] [varchar](max) NULL,
[faceBitmap] [varchar](max) NULL,
[faceAttestationAccepted] [bit] NULL,
[EnrollmentDateTime] [datetime] NULL,
CONSTRAINT [PK_FaceEnrollments] PRIMARY KEY CLUSTERED
(
[EmployeeNo] ASC,
[TIN] ASC
)
);
';
Also I recommand the better and more flexible sp originally created by Aaron Bertrand, you can download from Github for free :
SQL-Server-First-Responder-Kit/sp_ineachdb
which you can use exclude_list or exclude_pattern parameter to exclude databases:
exec [dbo].[sp_ineachdb]
#exclude_list = 'List of excluded databases'
#command = 'CREATE TABLE [dbo].[FaceEnrollments](...)'

Replacing a trigger with a stored procedure

I'm trying to replace a trigger statement with a stored procedure since enabled triggers are not allowed when using the tables in microsoft powerapps.
Simplified, I have to tables:
KPI_Dim (KPI_ID [PK] , KPIName, KPIGroup...)
KPICurrent_Fact (KPI_key [FK i.e KPI_Dim[KPI_ID], KPICurrent_ID, KPI_Value...)
Currently, for every new record in KPI_Dim my trigger adds a new row in KPICurrent_Fact with the FK and an autoincremented PK. The rest of the columns e.g. KPI_Value are supposed to be empty.
My simple trigger looks like this:
CREATE TRIGGER [dbo].[trg_insert_newKPI]
ON [dbo].[KPI_Dim]
FOR INSERT AS
INSERT INTO KPICurrent_Fact (KPI_key)
SELECT KPI_ID
FROM INSERTED
Now, I want to create a stored procedure that can achieve exactly the same. I have tried to find a solution myself but I'm new to stored procedures and could not find anything that would replicate a trigger.
I'm using SSMS v.18.4.
Thank you for any suggestions.
EDIT
Added Table creation and insert into statement code.
/* Create KPI_Dim table*/
CREATE TABLE [dbo].[KPI_Dim](
[KPI_ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[KPIName] [varchar](200) NOT NULL,
[KPIDescription] [varchar](500) NULL,
[KPIGroup] [varchar](100) NOT NULL,
[KPISubGroup] [varchar](100) NULL,
[KPIOwner] [varchar] (50) NOT NULL,
[DateCreated] DATETIME NULL DEFAULT(GETDATE())
)
/* Example data */
INSERT INTO [dbo].[KPI_Dim]
(
KPIName,
KPIDescription,
KPIGroup,
KPISubGroup,
KPIOwner
)
VALUES
('TestKPIName','testtest','TestGroup', 'TestSubGroup', 'TestOwner');
You can go for OUTPUT Clause and insert into table variable. From the table variable, you can insert into fact table.
CREATE TABLE [dbo].[KPI_Dim](
[KPI_ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[KPIName] [varchar](200) NOT NULL,
[KPIDescription] [varchar](500) NULL,
[KPIGroup] [varchar](100) NOT NULL,
[KPISubGroup] [varchar](100) NULL,
[KPIOwner] [varchar] (50) NOT NULL,
[DateCreated] DATETIME NULL DEFAULT(GETDATE())
)
CREATE TABLE dbo.KPI_Fact
(
[KPI_ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[KPIDIMID] INT NULL FOREIGN KEY references [dbo].[KPI_Dim]([KPI_ID])
)
DECLARE #inserted table(KPI_DIMID INT)
INSERT INTO [dbo].[KPI_Dim]
(
KPIName,
KPIDescription,
KPIGroup,
KPISubGroup,
KPIOwner
)
OUTPUT inserted.KPI_ID INTO #inserted
VALUES
('TestKPIName','testtest','TestGroup', 'TestSubGroup', 'TestOwner');
INSERT INTO dbo.KPI_Fact([KPIDIMID])
SELECT * FROM #inserted
KPI_ID
KPIDIMID
1
1

SQL Server Bulk Insert Failure

Consider the table:
CREATE TABLE [dbo].[inputdata](
[Name] [varchar](150) NULL,
[AddressStreet] [varchar](150) NULL,
[AddressStreet2] [varchar](150) NULL,
[City] [varchar](150) NULL,
[State] [varchar](2) NULL,
[Zip] [varchar](5) NULL,
[Phone] [varchar](10) NULL,
[Campus] [varchar](50) NULL,
[Access] [varchar](50) NULL,
[Type] [varchar](50) NULL,
[Degree] [varchar](50) NULL,
[Unknown1] [varchar](50) NULL,
[Unknown2] [varchar](50) NULL,
[IdentType] [varchar](50) NULL,
[Unknown3] [varchar](50) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
And the insert script:
SET ANSI_DEFAULTS ON
BULK INSERT dbo.inputdata
FROM 'C:\inputdata.csv'
WITH (
FIELDTERMINATOR = ','
,ROWTERMINATOR='\n'
)
Why is the following error output:
The bulk load failed. The column is too long in the data file for row 1, column 15. Verify that the field terminator and row terminator are specified correctly.
DataRow 1 (I manually added the \n for this question, the character exists in each row from the file):
1CRESCENT CITY BARTENDING INSTITUTE,209 N. BROAD AVE., ,NEW ORLEANS,LA,70119,.,Regular,Private,1-2 years,Diploma, , ,IPEDSUNIT,158617,\n
I tried to recreate your problem and everything worked.
Until I tried converting the file into UNIX format, where the linefeed is different. This got me the following message:
Bulk load data conversion error (truncation) for row 1, column 15 (Unknown3).
Try to look at your file with a hex editor.
There is an extra field terminator at the end of the line. An extra field terminator can cause it to throw general errors.
I hope this helps!
One way to ensure files get loaded that have strange items like an extra field terminator or text qualified fields using a bulk insert is using a format file. The link below explains how to create one of those files.
http://technet.microsoft.com/en-us/library/ms191479(v=sql.105).aspx

How do I insert into two tables all at once in a stored procedure? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I INSERT data into two tables simultaneously in SQL Server?
Doing a project for school so any help would be great thank you!
I have two tables - how do I insert into two tables? So both tables are linked.
First table is called Customer with primary key called CID that auto increments
CREATE TABLE [dbo].[Customer](
[CID] [int] IDENTITY(1,1) NOT NULL,
[LastName] [varchar](255) NOT NULL,
[FirstName] [varchar](255) NOT NULL,
[MiddleName] [varchar](255) NULL,
[EmailAddress] [varchar](255) NOT NULL,
[PhoneNumber] [varchar](12) NOT NULL
CONSTRAINT [PK__CInforma__C1F8DC5968DD69DC] PRIMARY KEY CLUSTERED
(
And a second table called Employment that has a foreign key linked to the parent table
CREATE TABLE [dbo].[Employment](
[EID] [int] IDENTITY(1,1) NOT NULL,
[CID] [int] NOT NULL,
[Employer] [varchar](255) NOT NULL,
[Occupation] [varchar](255) NOT NULL,
[Income] [varchar](25) NOT NULL,
[WPhone] [varchar](12) NOT NULL,
CONSTRAINT [PK__Employme__C190170BC7827524] PRIMARY KEY CLUSTERED
(
You need to do something like this:
DECLARE #NewID INT
INSERT INTO Customer(LastName,FirstName,......) VALUES(Value1, Value2, .....)
SELECT #NewID = SCOPE_IDENTITY()
INSERT INTO Employment(CID,Employer,.....) VALUES(#NewID, ValueA,..........)
SCOPE_IDENTITY: Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.

SQL Server 2008 find and replace elements in XML column

In the following table:
CREATE TABLE [dbo].[GDB_ITEMS](
[ObjectID] [int] NOT NULL,
[UUID] [uniqueidentifier] NOT NULL,
[Type] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](226) NULL,
[PhysicalName] [nvarchar](226) NULL,
[Path] [nvarchar](512) NULL,
[Url] [nvarchar](255) NULL,
[Properties] [int] NULL,
[Defaults] [varbinary](max) NULL,
[DatasetSubtype1] [int] NULL,
[DatasetSubtype2] [int] NULL,
[DatasetInfo1] [nvarchar](255) NULL,
[DatasetInfo2] [nvarchar](255) NULL,
[Definition] [xml] NULL,
[Documentation] [xml] NULL,
[ItemInfo] [xml] NULL,
[Shape] [geometry] NULL,
CONSTRAINT [R2_pk] PRIMARY KEY CLUSTERED
(
[ObjectID] ASC
)
ALTER TABLE [dbo].[GDB_ITEMS] WITH CHECK ADD CONSTRAINT [g1_ck] CHECK (([Shape].[STSrid]=(4326)))
GO
The [Documentation] column contains several hundred xml items and elements. I am trying to figure out to, with T-SQL, replace one series of elements:
<NPS_Info>
<MetaPurp>NPS</MetaPurp>
<NPS_Unit>
<UnitCode>MANDATORY for Data Store: NPS Alpha Unit Code (ACAD)</UnitCode>
<UnitType>MANDATORY for Data Store: NPS Unit Type (National Park, National Monument, etc)</UnitType>
</NPS_Unit>
</NPS_Info>
With this:
<NPS_Info>
<MetaPurp>NPS</MetaPurp>
<MetaPurp>CSDGM</MetaPurp>
<MetaPurp>OnlineData</MetaPurp>
<NPS_Unit>
<UnitCode>ABCD</UnitCode>
<UnitType>Park</UnitType>
</NPS_Unit>
<DatStore>
<Category>Landscape</Category>
<Category>Monitoring</Category>
<Category>Resource Management</Category>
<DSteward>
<cntinfo>
<cntperp>
<cntper>Something</cntper>
</cntperp>
<cntaddr>
<addrtype>mailing and physical</addrtype>
<address>1 Smith Lane</address>
<address></address>
<city>Anywhere</city>
<state>ST</state>
<postal>12345</postal>
</cntaddr>
<cntemail>email#email.com</cntemail>
</cntinfo>
</DSteward>
</DatStore>
</NPS_Info>
Please forgive my clumsy cut n' paste. There are several thousand rows in this table, however, not all of them have the xml element described in the first code block (this is a global table that holds descriptions of ALL tables in the DB, some [Documentation] records will contain non-pertinent xml not of interest to this operation).
You can use XML Data Modification Language (XML DML)
This code will change the content of the first node named NPS_Info with the content in variable #XML.
-- Delete everything in node NPS_Info
update YourTable
set XMLCol.modify('delete //NPS_Info[1]/*')
-- Insert #XML to node NPS_Info
update YourTable
set XMLCol.modify('insert sql:variable("#XML") into (//NPS_Info)[1]')
Working sample on SE Data