I have the following temp tables
CREATE TABLE #Test2ABCD
( VenueID int NOT NULL
, VenueName nvarchar(max)
, VenueAdd nvarchar(max)
, VenueCity nvarchar(max)
, VenueState nvarchar(max)
, VenueCounty nvarchar(max)
, VenueZip nvarchar(max)
, VenuePhone nvarchar(max)
, VenueFax nvarchar(max)
, VenueContactName nvarchar(max)
, VenueContactEmail nvarchar(max)
, VenueContactPhone nvarchar(max)
, VenueWebsite nvarchar(max)
, VenueLat float
, VenueLong float
, VenueRating nvarchar(max)
, MapURL nvarchar(max)
, XMLResult xml);
and
CREATE TABLE #SprocRes2ABCD
( RowID int identity(1,1) not null
, GPSLatitude float
, GPSLongitude float
, City nvarchar(max)
, State nvarchar(max)
, PostalCode nvarchar(max)
, Address nvarchar(max)
, County nvarchar(max)
, MapURL nvarchar(max)
, XMLResults xml);
When I try to execute the following merge statement
MERGE INTO #Test2ABCD t
USING #SprocRes s ON (t.VenueID=s.RowID)
WHEN MATCHED THEN
UPDATE SET t.VenueCounty = s.County
, t.VenueLat = s.GPSLatitude
, t.VenueLong = s.GPSLongitude;
I get the following error:
Msg 207, Level 16, State 1, Line 18
Invalid column name 'RowID'.
I know this has something to do with the "RowId" Column being an identity column but does anyone know how to fix this?
OK so it seems that my eyes have stopped functioning! It was indeed a typo in the final line. Thank you very much for the code review
Related
We have set up a merge replication in SQL Server. One of our biggest deadlocks is this stored procedure up above that is run by subscribers.
CREATE PROCEDURE sys.sp_MSmakegeneration
#gencheck int = 0,
#commongen bigint = NULL,
#commongenguid uniqueidentifier = NULL,
#commongenvalid int = NULL OUTPUT,
#compatlevel int = 90
AS
SET NOCOUNT ON
DECLARE #gen bigint
, #replnick binary(6)
, #dt datetime
, #art_nick int
, #first_ts int
, #makenewrow bit
, #retcode smallint
, #nickbin varbinary(255)
, #maxgendiff_fornewrow bigint
, #count_of_articles int
, #lock_acquired bit
, #lock_resource nvarchar(255)
, #procfailed bit
, #delete_old_genhistory bit
, #close_old_genhistory bit
, #changecount int
, #dbname nvarchar(258)
, #processing_order int
, #prev_processing_order int
, #prev_art_nick int
, #force_leveling bit
, #gen_change_threshold int
declare #cmd nvarchar(4000)
declare #old_bi_gen bigint
declare #bi_view_objid int
--declare #GENSTATUS_OPEN tinyint
--declare #GENSTATUS_MERGE_INSERTED_OPEN tinyint
--declare #GENSTATUS_LOCAL_CLOSED tinyint
--declare #GENSTATUS_TEMPORARILY_CLOSED tinyint
What does this stored procedure exactly do here?
And why should it be repeatedly called while it exists there?
Is there script/procedure/function that can generate a CREATE TABLE statement from an arbitrary SQL query?
When building procedures, I'd like to have a quick way to generate a temporary table, rather than having to review the table definitions of all of the tables referenced in the query.
Simple example:
SELECT p.pat_id, pat_name,
enc_id, admsn_time, disch_time
FROM patient p
INNER JOIN encounter e ON p.pat_id=e.pat_id
WHERE admsn_time >= '01/01/2014'
Would generate (columns' data definition is retrieved from the system table):
-- randomly-generated table name
CREATE TABLE #random_name (
PAT_ID VARCHAR(18) NOT NULL,
PAT_NAME VARCHAR(200),
ENC_ID NUMERIC(18,0) NOT NULL,
ADMSN_TIME DATE,
DISCH_TIME DATE
)
SSMS workflow:
select the text
right click, select Generate CREATE TABLE statement (function/script/proc called; result placed on clipboard)
place cursor in desired location
paste
This is a bit of a hack, but you could try selecting into a table (see line #3):
SELECT p.pat_id, pat_name,
enc_id, admsn_time, disch_time
INTO delete_me
FROM patient p
INNER JOIN encounter e ON p.pat_id=e.pat_id
WHERE admsn_time >= '01/01/2014'
Then you can highlight the delete_me table in SSMS, right-click, and generate the CREATE TABLE script.
Finally, you'd want to DROP TABLE delete_me to clean up.
use
SELECT p.pat_id, pat_name,
enc_id, admsn_time, disch_time
into #randomtable
FROM patient p
INNER JOIN encounter e ON p.pat_id=e.pat_id
WHERE admsn_time >= '01/01/2014'
and your table will be created when you execute the statement.
First of all, I would make a stored procedure of the query. (It keeps me from forgetting it later)
Secondly, I would write a query to generate the table for me:
DECLARE #CREATE_TABLE_QUERY NVARCHAR(MAX) = N'';
SELECT
#CREATE_TABLE_QUERY += ', ' + name + ' ' + UPPER(system_type_name) + CHAR(13) + CHAR(10) + CHAR(9)
FROM
sys.dm_exec_describe_first_result_set('YOUR_PROCEDURE_NAME_HERE', NULL, 1);
SELECT
#CREATE_TABLE_QUERY = N'CREATE TABLE TABLE_NAME_HERE(' + CHAR(13) + CHAR(10) + CHAR(9) + STUFF(#CREATE_TABLE_QUERY, 1, 1, N'') + ');';
PRINT #CREATE_TABLE_QUERY;
Note: Replace 'YOUR_PROCEDURE_NAME_HERE' with the name of your own stored procedure.
Note: Replace TABLE_NAME_HERE with the table name of your choice.
The above will generate something like this:
CREATE TABLE TABLE_NAME_HERE(
WeekName VARCHAR(40)
, Line Name VARCHAR(50)
, TheDate DATETIME
, ReceivedAll INT
, Answered INT
, Abandoned INT
, Call Length INT
, WaitTimeAnswer INT
, WaitTimeAbandon INT
, PeriodName VARCHAR(10)
, Week SMALLINT
, Period SMALLINT
, Year SMALLINT
, WeekInPeriod SMALLINT
, NumWeeksInPeriod SMALLINT
, WeekendDate DATETIME
, CRCOperative VARCHAR(100)
, CallType VARCHAR(20)
, Charge Time INT
, SourceNumber VARCHAR(80)
, DestinationNumber VARCHAR(80)
, CallStart DATETIME
, Out of Hours VARCHAR(12)
, IsWorkingDay BIT
);
I have a log table has xml column which contains log contents
There is also table called logType which is the type of log
I need to create query descripes the xml contents as readable string
I added a column with name logXPath to logtype table
and i created the following query
SELECT contents.value(LogXPath, 'nvarchar(max)')
FROM dbo.Log
JOIN dbo.LogType ON dbo.Log.logTypeID = dbo.LogType.logTypeID
and I got the following error
The argument 1 of the XML data type method "value" must be a string literal
and I searched for a way to do this with no results!!
Is there any do dynamic xpath in Sql Server XML Column?
Edit
for example assume the following schema and data
CREATE TABLE [dbo].[logType]
(
[logTypeID] [int] NOT NULL ,
[logTypeName] [nvarchar](50) NOT NULL ,
[xPath] [nvarchar](MAX) NOT NULL ,
CONSTRAINT [PK_logType] PRIMARY KEY CLUSTERED ( [logTypeID] ASC )
)
GO
INSERT [dbo].[logType]
( [logTypeID] ,
[logTypeName] ,
[xPath]
)
VALUES ( 1 ,
N'Patient Data' ,
N'(/Patient/PatientName)[1]'
)
INSERT [dbo].[logType]
( [logTypeID] ,
[logTypeName] ,
[xPath]
)
VALUES ( 2 ,
N'Clinic Data' ,
N'(/Clinic/ClinicName)[1]'
)
/****** Object: Table [dbo].[log] Script Date: 02/04/2015 13:58:47 ******/
GO
CREATE TABLE [dbo].[log]
(
[logID] [int] NOT NULL ,
[logTypeID] [int] NOT NULL ,
[Contents] [xml] NULL ,
CONSTRAINT [PK_log] PRIMARY KEY CLUSTERED ( [logID] ASC )
)
GO
INSERT [dbo].[log]
( [logID] ,
[logTypeID] ,
[Contents]
)
VALUES ( 1 ,
1 ,
N'<Patient><PatientID>1</PatientID><PatientName>john</PatientName></Patient>'
)
INSERT [dbo].[log]
( [logID] ,
[logTypeID] ,
[Contents]
)
VALUES ( 2 ,
2 ,
N'<Clinic><ClinicID>1</ClinicID><ClinicName>Clinic 1</ClinicName></Clinic>'
)
When I make query like the following ,it gives me the error
SELECT logTypeName ,
[Contents].value(dbo.logType.xPath, 'nvarchar(max)') AS data
FROM dbo.[log]
JOIN dbo.logType ON dbo.[log].logTypeID = dbo.logType.logTypeID
You can build a query dynamically using the table LogType.
declare #SQL nvarchar(max);
set #SQL = 'select case L.logTypeID'+
(
select ' when '+cast(LT.logTypeID as varchar(11))+
' then L.Contents.value('''+LT.xPath+''', ''nvarchar(max)'')'
from LogType as LT
for xml path('')
)+' end as Name from dbo.[Log] as L;';
exec (#SQL);
It will give you a query that looks like this:
select case L.logTypeID
when 1 then L.Contents.value('(/Patient/PatientName)[1]', 'nvarchar(max)')
when 2 then L.Contents.value('(/Clinic/ClinicName)[1]', 'nvarchar(max)')
end as Name
from dbo.[Log] as L;
Okay, so this has been here a while (a year), but this might be helpful...
A VERY helpful TABLE function: http://beyondrelational.com/modules/2/blogs/28/posts/10495/xquery-lab-58-select-from-xml.aspx
Using that function, you can get the values you're after something like this:
Select l.Contents, t.XPath, x.Value
From [log] l With (NoLock)
Inner Join [LogType] t With (NoLock)
on t.LogTypeID=l.LogTypeID
CROSS APPLY XMLTable(l.Contents) AS x
Where REPLACE(REPLACE(REPLACE(t.XPath,'[1]',''),'(',''),')','')=REPLACE('/'+x.XPath,'[1]','')
SQL Server does not allow replacing entire XPath expression with a variable, but you can use sql:variable and sql:column extensions inside the expression (I can't say how exactly without seeing your xml structure and what information you want to query from XML column).
Or, as mentioned above, you can use dynamic SQL:
DECLARE #xpath NVARCHAR(MAX);
SET #xpath = ... //Calculate xpath expression here
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT contents.value(''' + #xpath + ''', ''NVARCHAR(MAX)''
FROM dbo.Log
JOIN dbo.LogType ON dbo.Log.logTypeID = dbo.LogType.logTypeID';
EXEC sp_executesql #sql;
ALTER PROCEDURE EditEmployee (
#RefNo integer ,
#EmpId nvarchar ,
#Name ntext ,
#Designation ntext ,
#Qualification ntext ,
#Gender ntext ,
#DOB date ,
#Address text ,
#Email ntext ,
#Phone decimal )
as
begin
UPDATE Emp_Sample
SET RefNo=#RefNo,Name=#Name,Designation=#Designation,
Qualification=#Qualification,Gender=#Gender,
DOB=#DOB,Address=#Address,Email=#Email,
Phone=#Phone
where EmpId=#EmpId
END
You need to include #EmpId nvarchar size .
ALTER PROCEDURE EditEmployee (
#RefNo integer ,
#EmpId nvarchar(30) ,
nvarchar [ ( n | max ) ]
When n is not specified in a data definition or variable declaration statement, the default length is 1. When n is not specified with the CAST function, the default length is 30.
HERE
I think you have Cast Problem
Try like this
WHERE EmpId = CAST(#EmpId AS INT)
I'm unable to use a pivot the data of a table variable.
Its giving following error on run-time:
"Must declare the scalar variable #reportData"
I have tried as mentioned below
DECLARE #reportData TABLE
(
PERSONID NUMERIC(6,0),
personname VARCHAR(100),
bu VARCHAR(50),
timeperiod VARCHAR(100),
wfstatus VARCHAR(100)
)
I'm using the below dynamic pivot query
declare #query nvarchar(max)
set #query=N'SELECT PERSONID,PERSONNAME,BU,wfstatus,'+#datelist+'
from(
SELECT PERSONID,PERSONNAME,BU,wfstatus,timeperiod
FROM
'+#reportData+') AS SOURCETABLE
PIVOT
(group by wfstatus
FOR timeperiod
IN('+#datelist+')
) as pivorttable
select personid,personname,bu,timeperiod,status from pivorttable'
execute(#query);
can some one help me in this?
I need to use only table variable to maintain concurrency issue.!
FROM'+#reportData attempts to add a table variable to a string, which wont work as a table variable is not a string.
Given that you presumably need to populate reportData first you could switch to an explicitly created temp table
create table #reportData
(
PERSONID NUMERIC(6,0)
...
)
Or use a Table Type;
--run once
CREATE TYPE ReportDataType AS TABLE (
PERSONID NUMERIC(6,0),
personname VARCHAR(100)
)
declare #reportData ReportDataType
insert #reportData values
(111, 'bob'),
(222, 'alice')
declare #query nvarchar(max) = N'select * from #T'
exec sp_executesql #query, N'#T ReportDataType readonly', #reportData