I just installed SQL Server 2016 and SP1 and run this TSQL Script
CREATE TABLE [dbo].TEST(
[id] [INT] IDENTITY(1,1) NOT NULL,
[lat] [DECIMAL](9, 6) NULL,
[lng] [DECIMAL](9, 6) NULL,
[Location] AS ([geography]::STGeomFromText(((('POINT ('+[lng])+' ')+[lat])+')',(4326)))
PERSISTED
)
The table is created fine.
I then run the following (there is no records in the table)
Select * from TEST
This returns
Msg 8114, Level 16, State 5, Line 8
Error converting data type varchar to numeric.
It is related to the Location field.
Is this a bug in SQL Server 2016? I would not expect this behavior.
The following does not cause any issues
CREATE TABLE [dbo].TEST2(
[id] [INT] IDENTITY(1,1) NOT NULL,
[lat] [DECIMAL](9, 6) NULL,
[lng] [DECIMAL](9, 6) NULL,
[Location] AS [lng] PERSISTED
)
select * from TEST2
Change
[Location] AS ([geography]::STGeomFromText(((('POINT (' + [lng]) + ' ') + [lat]) + ')', (4326)))
to
[Location] AS ([geography]::STGeomFromText(((('POINT (' + CAST([lng] AS varchar)) + ' ') + CAST([lat] AS varchar)) + ')', (4326)))
The difference in these two are the usage of the CAST function like so:
CAST([lng] AS varchar)
CAST([lat] AS varchar)
Simply an issue of [lng] and [lat] being decimals concatenated to a varchar string. The reason for it not being a problem until you actually execute the query even with no data in the table is due to the [Location] field not being formed until the select query is executed.
Not a bug necessarily but something that SQL Management Studio should probably parse for prior to executing the CREATE TABLE query.
You need to CAST the lng and lat values to varchar so the + operator is treated as concatenation instead of addition. Example without the extraneous parenthesis:
CREATE TABLE [dbo].TEST(
[id] [INT] IDENTITY(1,1) NOT NULL,
[lat] [DECIMAL](9, 6) NULL,
[lng] [DECIMAL](9, 6) NULL,
[Location] AS [geography]::STGeomFromText('POINT ('+ CAST([lng] AS varchar(10)) + ' ' + CAST([lat] AS varchar(10)) + ')', 4326)
PERSISTED
);
Related
I am having an issue with a dynamic query to pivot on an unknown number of columns in MS SQL server 2014. I've based my query on the article SQL Server 2005 Pivot on Unknown Number of Columns and other similar articles. However, I am having two issues that I can't decipher.
When executing the dynamic SQL, I get this error:
The name 'SELECT Code, LastName, FirstName, [03-30-2021],[06-30-2021],[08-00-2021],[10-30-2021],[12-30-2021],[17-30-2021],[18-30-2021],[19-30-2021],[20-30-2021],[21-30-2021],[22-30-2021],[24-30-2021],[25-30-2021],[26-30-2021],[29-30-2021] FROM (
SELECT i.Code, aa.LastName, aa.FirstName, FORMAT(StartDate, 'dd-mm-yyyy') AS StartDate, FORMAT(s.SignOut-s.SignIn, 'hh:mm') AS AttendanceTime
FROM ActualSession AS a INNER JOIN ActualAttendee aa ON( a.id = aa.ActualSessionId)
INNER JOIN Attendee att ON (att.Id = aa.AttendeeId)
LEFT JOIN SignIn s ON (a.Id = s.ActualSessionId) LEFT JOIN Identification i ON (i.AttendeeId = aa.AttendeeId
AND i.Id' is not a valid identifier.
However, if I copy and paste the query into a separate window in SQL Server Management Studio, it runs... I can't see what is wrong, except that the error message is only returning the first xxx characters of the query... Any suggestions as to what I have done wrong would be appreciated. Is it the joins, or the way I've selected columns?
BUT... that takes me to the second issue. When I do run the copied query text separately, it works but it is showing the same values (time in hours/minutes) for all users, rather than the user-specific values (though users who did not sign in are correctly coming up NULL). The pivot seems to need a min/max/other aggregate, but where it should be keeping it to each user (according to what I can see, by some SQL voodoo), it's not... The column names also appear to be coming up in US date format, even though I've specified the format as Australian (dd-mm-yyyy). If anyone knows how to correct these issues, that would also be appreciated.
Code LastName FirstName 03-30-2021 06-30-2021 08-00-2021 10-30-2021
abc123 Simpson Homer 01:07 01:15 NULL 01:01
abc456 Griffen Peter 01:07 01:15 NULL 01:01
abc789 Flintsone Fred 01:07 01:15 NULL 01:01
xyz123 Heffernan Doug 01:07 01:15 NULL 01:01
xyz456 Gergich Jerry NULL NULL NULL NULL
xyz789 Kramden Ralph 01:07 01:15 NULL 01:01
The full query I am running is:
#Query AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT DISTINCT '],[' + FORMAT(StartDate, 'dd-mm-yyyy') FROM ActualSession
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,2,'') + ']'
SET #Query = 'SELECT Code, LastName, FirstName, ' + #cols + ' FROM (
SELECT i.Code, aa.LastName, aa.FirstName, FORMAT(StartDate, ''dd-mm-yyyy'') AS StartDate, FORMAT(s.SignOut-s.SignIn, ''hh:mm'') AS AttendanceTime
FROM ActualSession AS a INNER JOIN ActualAttendee aa ON( a.id = aa.ActualSessionId)
INNER JOIN Attendee att ON (att.Id = aa.AttendeeId)
LEFT JOIN SignIn s ON (a.Id = s.ActualSessionId) LEFT JOIN Identification i ON (i.AttendeeId = aa.AttendeeId
AND i.IdentificationTypeId = (SELECT Id FROM IdentificationType WHERE [Name] = ''Student Code''))
) x PIVOT ( max(AttendanceTime)
FOR StartDate in (' + #cols + ') ) p '
PRINT #Query --for debugging
execute #Query
Relevant Table definitions are:
CREATE TABLE [dbo].[ActualSession](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[EventId] [bigint] NOT NULL,
[EventName] [nvarchar](50) NOT NULL,
[EventSessionId] [bigint] NOT NULL,
[StartDate] [datetime] NOT NULL,
[EndDate] [datetime] NOT NULL,
[Active] [bit] NULL,
[SignInRequired] [bit] NULL,
[SignOutRequired] [bit] NULL,
[SignInAllowed] [bit] NULL,
[SignOutAllowed] [bit] NULL,
[EarlySignInAllowed] [bit] NULL,
[EarlySignOutAllowed] [bit] NULL,
[LateSignInAllowed] [bit] NULL,
[LateSignOutAllowed] [bit] NULL,
[ExpiredIdAllowed] [bit] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Attendee](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[PreferredName] [nvarchar](50) NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[SignIn](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[EventId] [bigint] NOT NULL,
[ActualSessionId] [bigint] NOT NULL,
[AttendeeId] [bigint] NOT NULL,
[SignIn] [datetime] NOT NULL,
[SignOut] [datetime] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Identification](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[AttendeeId] [bigint] NOT NULL,
[IdentificationTypeId] [bigint] NOT NULL,
[Code] [nvarchar](50) NOT NULL,
[ExpiryDate] [date] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[IdentificationType](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[RevHex] [bit] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[ActualAttendee](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[EventId] [bigint] NOT NULL,
[ActualSessionId] [bigint] NOT NULL,
[AttendeeId] [bigint] NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[PreferredName] [nvarchar](50) NULL,
[GroupId] [bigint] NULL,
[GroupName] [nvarchar](50) NULL,
[GroupTypeId] [bigint] NULL,
[GroupTypeName] [nvarchar](50) NULL,
[GroupTypeAD] [bit] NULL,
[GroupTypeADName] [nvarchar](200) NULL,
[GroupTypeDB] [bit] NULL,
[GroupTypeDBQuery] [nvarchar](1000) NULL,
[GroupTypeManual] [bit] NULL
) ON [PRIMARY]
GO
You have two issues here:
Your main issue: when you call execute you need to enclose #Query in parenthesis (). I suggest, though, that you use sp_executesql, because this enables you to pass through parameters if necessary
Your second problem: don't try to quote the column names yourself, use QUOTENAME
DECLARE #Query AS nvarchar(MAX), #cols nvarchar(MAX);
SELECT #cols = STUFF((
SELECT DISTINCT ',' + QUOTENAME(FORMAT(StartDate, 'dd-mm-yyyy'))
FROM ActualSession
FOR XML PATH(''), TYPE
).value('text()[1]', 'NVARCHAR(MAX)')
, 1, LEN(','), '');
SET #Query = '
SELECT
Code,
LastName,
FirstName,
' + #cols + '
FROM (
SELECT
i.Code,
aa.LastName,
aa.FirstName,
FORMAT(StartDate, ''dd-mm-yyyy'') AS StartDate,
FORMAT(s.SignOut-s.SignIn, ''hh:mm'') AS AttendanceTime
FROM ActualSession AS a
INNER JOIN ActualAttendee aa ON (a.id = aa.ActualSessionId)
INNER JOIN Attendee att ON (att.Id = aa.AttendeeId)
LEFT JOIN SignIn s ON (a.Id = s.ActualSessionId)
LEFT JOIN Identification i ON (i.AttendeeId = aa.AttendeeId
AND i.IdentificationTypeId = (SELECT Id FROM IdentificationType WHERE [Name] = ''Student Code''))
) x
PIVOT ( max(AttendanceTime)
FOR StartDate in (
' + #cols + '
) ) p;
';
PRINT #Query --for debugging
EXEC sp_executesql #Query;
I believe the error you are receiving is related to the usage of execute #Query instead of execute (#Query). Looking at the Microsoft doc on EXECUTE, executing a string variable requires open and close parens:
Execute a character string
{ EXEC | EXECUTE }
( { #string_variable | [ N ]'tsql_string' } [ + ...n ] )
[ AS { LOGIN | USER } = ' name ' ]
[;]
Once I added the parens, I was able to get what I believe is an equivalent statement to yours to execute as expected with some sample data I created.
As for your date format, I believe your date format string has an issue. I believe your current date format string of dd-mm-yyyy is meant to be dd-MM-yyyy. Per the Custom date and time format strings Microsoft doc (referenced by Microsoft doc on FORMAT):
"mm" The minute, from 00 through 59.
"MM" The month, from 01 through 12.
I have Two Table in sql server 2008
TABLE [tblTagDescription](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[TopicID] [int] NULL,
[TagID] [int] NULL,
[FullTag] [nvarchar](50) NULL,
[ValDecimal] [nvarchar](50) NULL,
[ValBinary] [nvarchar](50) NULL,
[GroupName] [nvarchar](50) NULL,
[ReportTag] [nvarchar](50) NULL
)
And
TABLE [tblDataLog](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[TagDescID] [bigint] NULL,
[Value] [decimal](18, 2) NULL,
[Date] [datetime] NULL,
)
Here there might be same Group for multiple "Id" of tblDescription and "TagDescID" of tblDataLog.
Here 'Group1' has 10 ID as from 1 to 10. and there might be multiple record for these ID (from 1 to 10) in tbldatalog. I want these ID from 1 to as columns. I want Average of these ID (From 1 to 10).
For this I used pivot:
Declare #COls nvarchar(max)
Declare #SQL nvarchar(max)
DECLARE #COlsID NVARCHAR(MAX) = ''
DECLARE #COlsAlias NVARCHAR(MAX) = ''
IF OBJECT_ID('tempdb..##MYTABLE') IS NOT NULL DROP TABLE ##MYTABLE
IF OBJECT_ID('tempdb..#tt') IS NOT NULL DROP TABLE #tt
IF(#Group='A')
BEGIN
Select #COls=COALESCE(#Cols + '],[','') + z.ReportTag From
(Select Distinct T.ID, ReportTag From tblTagDescription T
Where isnull(ReportTag,'')<>'' AND T.GroupName=#Group Group BY T.ID,T.ReportTag --order by T.ID
)z
END
ELSE
BEGIN
SELECT
#COlsID = #ColsID + ',' + z.TagDescID,
#COlsAlias = #COlsAlias + ',' + z.TagDescID + ' AS ' + z.ReportTag
FROM
(select TagDescID,ReportTag from(SELECT DISTINCT TOP 50 QUOTENAME(CONVERT(NVARCHAR(25),
tblDataLog.TagDescID )) TagDescID,TagdescID TID,
QUOTENAME(tblTagDescription.ReportTag) ReportTag
FROM tblDataLog
INNER JOIN tblTagDescription ON tblDataLog.TagDescID = tblTagDescription.ID
where tblTagDescription.GroupName=#Group
ORDER BY tblDataLog.TagDescID )s
) z
END
SET #COlsID= STUFF(#COlsID,1,1,'')
SET #COlsAlias= STUFF(#COlsAlias,1,1,'')
SET #SQL='select [DATE],SHIFT, ' + #COlsAlias + ' into ##MYTABLE from ( select [Date], AVG(Value), TagDescID,
(CASE
WHEN ((DATEPART(hour,[DATE]))>6 and (DATEPART(hour,[DATE]))<14) THEN ''A''
WHEN ((DATEPART(hour,[DATE]))>=14 and (DATEPART(hour,[DATE]))<22) THEN ''B''
WHEN ((DATEPART(hour,[DATE]))>=22 or (DATEPART(hour,[DATE]))<6) THEN ''C''
END )AS SHIFT
from tblDataLog Group by [Date],[TagDescID] )d pivot(max(Value) for TagDescID in (' + #COlsID + ')) piv;'
EXEC (#SQL)
select * from ##MYTABLE
But the above query is giving error as :
Msg 8155, Level 16, State 2, Line 8
No column name was specified for column 2 of 'd'.
Msg 207, Level 16, State 1, Line 8
Invalid column name 'Value'.
Msg 208, Level 16, State 0, Procedure Select_DataViewer, Line 58
Invalid object name '##MYTABLE'.
How to solve this?
I am trying to utilize Dynamic SQL that will parse in the file directory into an OpenRowSet(#Database). Right now I have a hard coded directory for the Excel File. The end result will be me creating an application that will take the user's file and import into the SQL table. From there I'll be merging and Match/Not Matching (Which is working properly). This is the last piece of the puzzle. I don't know why the error message is looking for my file in "C:\WINDOWS\system32\ "
My current error messages are:
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "The Microsoft Access database engine could not find the object 'C:\WINDOWS\system32\ C:\Users\GrimRieber\Desktop\isi test.xlsx'. Make sure the object exists and that you spell its name and the path name correctly. If 'C:\WINDOWS\system32\ C:\Users\GrimRieber\Desktop\isi test.xlsx' is not a local object, check your network connection or contact the server administrator.".
Msg 7303, Level 16, State 1, Line 1
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
Code:
declare #Database varchar(max)
select #Database = 'C:\Users\GrimRieber\Desktop\isi test.xlsx'
declare #sql varchar(Max)
select #sql = 'SELECT * FROM OPENROWSET(
''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0; Database= ' + #Database + '; HDR=YES; IMEX=1'',
''SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],[01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],[12],[Year]FROM [Data$]''
)'
IF OBJECT_ID('tempdb.dbo.#TempScorecardInventorySold', 'U') IS NOT NULL
DROP TABLE #TempScorecardInventorySold;
CREATE TABLE #TempScorecardInventorySold
(
[Vendor] [varchar](50) NULL,
[VendorName] [varchar](50) NULL,
[Material] [varchar](50) NULL,
[MaterialName] [varchar](50) NULL,
[Supplier Stock Num] [varchar](50) NULL,
[01] [nVarchar](50) NULL,
[02] [nVarchar](50) NULL,
[03] [nVarchar](50) NULL,
[04] [nVarchar](50) NULL,
[05] [nVarchar](50) NULL,
[06] [nVarchar](50) NULL,
[07] [nVarchar](50) NULL,
[08] [nVarchar](50) NULL,
[09] [nVarchar](50) NULL,
[10] [nVarchar](50) NULL,
[11] [nVarchar](50) NULL,
[12] [nVarchar](50) NULL,
[Year] [Int] Null
) ON [PRIMARY];
INSERT INTO [dbo].#TempScorecardInventorySold ([Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],[01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],[12],[Year])
EXECUTE(#sql)
While I cannot recreate your file path issue (be sure to carefully check if file exists at the path and file extension), the OPENROWSET() in that setup should define fields in the SELECT clause at beginning. The last argument should be unquoted, pointing to worksheet range:
select #sql = 'SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],
[01],[02],[03],[04],[05],[06],
[07],[08],[09],[10],[11],[12],[Year]
FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0; Database= ' + #Database + '; HDR=YES; IMEX=1'', [Data$])';
Alternatively, consider OPENDATASOURCE:
select #sql = 'SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],
[01],[02],[03],[04],[05],[06],
[07],[08],[09],[10],[11],[12],[Year]
FROM OPENDATASOURCE(''Microsoft.ACE.OLEDB.12.0'',
''Data Source=' + #Database + ';Extended Properties=Excel 12.0'')...Data$'
Or even a Driver version (fields can be in either of two SELECT clauses)
select #sql = 'SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],
[01],[02],[03],[04],[05],[06],
[07],[08],[09],[10],[11],[12],[Year]
FROM OPENROWSET(''MSDASQL'',
''Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};
DBQ=' + #Database + ''', ''SELECT * FROM [DATA$]'');
Say I have a table Name_Address as follows:
CREATE TABLE [dbo].[Name_Address](
[First_Name] [nvarchar] (50) NULL,
[Last_Name] [nvarchar] (50) NULL,
[Address] [nvarchar] (50) NULL,
[City] [nvarchar] (50) NULL,
[State] [nvarchar] (50) NULL,
[Zip] [nvarchar] (50) NULL,
[Phone] [nvarchar] (50) NULL,
[Cell] [nvarchar] (50) NULL
) ON [PRIMARY]
Is there a way in SQL that I can build a string:
<First Name>John<Last Name>Smith<Address>1233 Your Street<City>Home Town<State>NY<Zip>123456-1234<Phone>111-111-1111<Cell>222-222-222
and insert it into another table?
Original post did not show the xml tags as part of the desired result: without code formatting the tags were interpreted literally and were not displayed.
You would just use the + to concatenate the values together.
INSERT INTO yourNewTable (newRecord)
SELECT First_Name + Last_Name + Address + City + State + Zip + Phone + Cell
FROM dbo.Name_Address
Or add spaces:
INSERT INTO yourNewTable (newRecord)
SELECT First_Name + ' ' + Last_Name + ' '
+ Address + ' ' + City + ' ' + State + ' ' + Zip
+ Phone + ' ' + Cell
FROM dbo.Name_Address
You can also use FOR XML PATH if you want this in XML format:
select *
from name_address
for xml path
see SQL Fiddle with Demo
Or you can hand-code the XML tags, if you want to insert the full record into another table you can use:
insert into yourNewTable (yourNewRecord)
select '<FirstName>'+[First_Name]
+ '<Last_Name>'+[Last_Name]
+'<Address>'+[Address]
+'<City>'+[City]
+'<State>'+[State]
+'<Zip>'+[Zip]
+'<Phone>'+[Phone]
+'<Cell>'+[Cell]
from name_address
see Sql Fiddle with Select Demo
INSERT INTO MyTable(MyString)
SELECT
'<FirstName>'+[First_Name] + '<Last_Name>'+[Last_Name] +'<Address>'+[Address] +<City>+[City] +<State>+[State] +'<Zip>'+[Zip] +'<Phone>'+[Phone] +'<Cell>'+[Cell]
FROM [dbo].[Name_Address]
You can concatenate fields together using ||:
select First_name||' '||Last_Name||' '+Address . . .
from NameAddress
To insert into another table, you can do something like:
insert into AnotherTable
select '<First Name>'||First_name||'<Last Name>'||Last_Name||'<Address>'+Address . . .
from NameAddress
I've read similar articles here in Stackoverflow, but i can't seem to make it work in my case.
I have column named (Date), with data type varchar, and the data throughout the whole column looks like this (1999-12-31-23-00-01) without parenthesis.
So, instead of Varchar, I want the same value, but in datetime format.
This is my table structure:
CREATE TABLE App
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Date] Varchar(50) NULL,
[Inst.nr] [smallint] NULL,
[Creator Initials] varchar NULL,
[AppOwner] varchar NULL,
[Status] varchar NULL,
[Serial.Nr] varchar NULL,
[MAC.Addr] varchar NULL,
[Dell.nr] varchar NULL,
[Model] varchar NULL,
[Description] varchar NULL,
[Service Warranty] [date] NULL,
[Purchased] [date] NULL,
)
Actually, the problem is not with the structure, its some old data from an Excel file, which was imported into SQL database.
In my [Date] column, which is in Varchar right now, The data inside this column looks like this 1999-12-31-23-00-01
As you can see, it looks like a datetime format, but it won't accept the conversion from varchar to datetime
Not sure if you are asking the conversion to datetime
SELECT
-- Convert using ISO date time yyyy-MM-dd hh:mm:ss
CONVERT(datetime,
LEFT(Date, 10) + ' ' +
REPLACE(RIGHT(Date, 8), '-', ':')
) AS DateInDatetime
FROM
(VALUES
-- assume format in yyyy-MM-dd-hh-mm-ss
('1999-12-31-23-00-01')
) t (Date)
SQL Fiddle
Use CONVERT function in Sql Server, convert to datetime follow format type 120:
SELECT CONVERT(DATETIME,SUBSTRING('(1999-12-31-23-00-01)',2,10) + ' ' + REPLACE(SUBSTRING('(1999-12-31-23-00-01)',13,8),'-',':'),120)
Hope this help!