SQL "WITH" doesn't work in Spotfire - sql-server

I try to run a query in Spotfire (7.8) from a MS SQL server.
Everything works well with simple queries, however I can't get Common table expressions get working.
This is a very simple example which run without issues from MS SQL Server Management studio:
with test as ( select * from myTable)
select * from test
In Spotfire I get following error:
An error occurred when executing a query in the external data source.
External error:
Incorrect syntax near the keyword 'with'.
Incorrect syntax near the keyword 'with'. If this statement is a
common table expression, an xmlnamespaces clause or a change tracking
context clause, the previous statement must be terminated with a
semicolon.
Incorrect syntax near ')'.
I've tried adding ; as suggested also here, but it didn't help:
An error occurred when executing a query in the external data source.
External error:
Incorrect syntax near ';'.
Incorrect syntax near ')'.
I've played a bit adding ;s to various location (after end of select statements, closing brackets...), but couldn't get it working.
My real query is very long, so putting everything together and getting rid of CTEs is not really an option.
Just for clarification, I've tried all below positions and also combinations without success:
;with test as ( select * from myTable)
select * from test
with test as ( select * from myTable;)
select * from test
with test as ( select * from myTable);
select * from test

TL;DR If you have all the right permissions, and have used Spotfire more than once or twice, make a stored procedure (see below for details). If you haven't, sorry, you're going to have to put the CTEs all together into one really long query.
So I have found that Spotfire will only actually run "one query" in a standard Information Link or Direct Connection.
Sadly, this means that it doesn't get along very well with temp tables or CTEs.
If leaving everything together really isn't an option, you will have to turn it into a stored procedure, as Sean mentioned in the comments.
The only downside to this, is it requires more access than a lot of Spotfire users have.
First things first, you will need to create your stored procedure in your database, or contact someone who can create the stored procedure for you.
Second, you will need to use the Information Designer (which, again, requires the correct permissions). If you have access, Information Designer is located under Tools. When you open it up, you will have "Create Information Link" at the top, and below that you will see things like "Create Elements" which includes "Procedure".
This is where you select the stored procedure from your data sources.
You then need to make an Information Link ("Create Information Link"), and select the Procedure you just built, which will now be in the "Elements" tab.

Related

linked server: four prefixes work with select but not alter

I have an SQL Server 13.0 box with
[EC2AMAZ\SQLEXPRESS] as a linked server
I'm running the following commands on the SQL Server 13.0 box
and this select statements work just fine:
select * from [EC2AMAZ\SQLEXPRESS].[import].[dbo].[table]
but this:
ALTER TABLE [EC2AMAZ\SQLEXPRESS].[import].[dbo].[table] ADD field
nvarchar(4000)
throws the error:
The object name 'EC2AMAZ\SQLEXPRESS.import.dbo.table' contains more than the maximum number of prefixes. The maximum is 2.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'field'.
why is it okay to use four prefixes for select but not alter?
You can't run DDL against a linked server. One workaround is to use dynamic SQL:
EXEC [EC2AMAZ\SQLEXPRESS].[import].sys.sp_executesql
N'ALTER TABLE [dbo].[table] ADD field nvarchar(4000);';
The syntax diagram in the official documentation does not include four-part names for ALTER TABLE:
It is officially documented (albeit indirectly) for SELECT in the docs for FROM {<table_source>}:
If the table or view exists outside the instance of SQL Serverl, use a four-part name in the form linked_server.catalog.schema.object.
(Typo is free!)
Such reference does not exist for ALTER TABLE. Yes, it kind of sucks that we have to infer from lack of documentation that something isn't possible, but imagine even trying to document all of the things a feature can't do?
This car:- cannot be used as a flotation device- is not a sufficient source of vitamin C- cannot vote- may not respond to "Betsy"- does not fly- will not fit into bell-bottoms- can't run on carrot juice, diet pepsi, or metamucil...
There is probably a long list of why, including the types of locks required to make schema modifications. But I suspect why isn't the thing that's important here, because answering that question isn't going to change the problem or help you avoid needing to use a workaround.

SQL Server Mgmt Studio shows "invalid column name" when listing columns?

I'm used to scripting in Python or Matlab, and my first couple hours with SQL have been infuriating. I would like to make a list of columns appear on the screen in any way, shape, or form; but when I use commands like
select *
from "2Second Log.dbo.TagTable.Columns"
I keep getting the error:
Invalid column name '[the first column in my table]'.
even though I never explicitly asked for [the first column in my table], it found it for me. How can you correctly identify the first column name, and then still claim it's invalid!? Babies will be strangled.
This db was generated by Allen Bradley's FactoryTalk software. What I would really like to do is produce an actual list of "TagName" strings...but I get the same error when I try that. If there were a way to actually double click the table and open it up and look at it (like in Matlab), that would be ideal.
Echoing juergen's suggestion in the comment above. It looks like you're running the query on the master database, not the 2Second Log database that actually has your table. (You can tell this by looking at the database in the dropdown in the top left of your screenshot). Two things you can do:
Change the dropdown in the top left to 2Second Log. This will target your query to a different database
Put your database name in brackets as suggested by juergen i.e. select * from [2Second Log].dbo.TagTable
As an side, if you're looking for a good SQL tutorial, I highly recommend the Mode SQL tutorial. It's a fantastic interactive platform to get your SQL feet wet.
always use brackets when names/field have spaces or dashes.
select * from [2Second Log].dbo.TagTable

Is one way of stating tables in a query more 'optimal' than another?

Edit: I'm aware that SELECT * is bad practice, but it's used here just to focus the example SQL on the table statement rather than the rest of the query. Mentally exchange it for some column names if you prefer.
Given a database server MyServer (which we are presently connected to in SSMS), with several databases MyDb1, MyDb2, MyDb3 etc and default schema dbo, are any of the following equivilant queries (they will all return exactly the same result set) more "optimal" than the others?
SELECT * FROM MyServer.MyDb1.dbo.MyTable
I was told that this method (explicitly providing the full database name including server name) treats MyServer as a linked server and causes the query to run slower. Is this true?
SELECT * FROM MyDb1.dbo.MyTable
The server name isn't required as we're already connected to it, but would this run 'faster' than the above?
USE MyDb1
GO
SELECT * FROM dbo.MyTable
State the database we're using initially. I can't imagine that this is any better than the previous for a single query, but would it be more optimal for subsequent queries on the same database (ie, if we had more SELECT statements in the same format below this)?
USE MyDb1
GO
SELECT * FROM MyTable
As above, but omitting the default schema. I don't think this makes any difference. Does it?
SQL Server will always look for the objects you sepcify within the current "Context" if you do not specify a fully qualified name.
Is one faster than the other, sure, the same as a file name on your hard drive of "This is a really long name for a file but at long as it is under 254 it is ok.txt" will take up more hard-drive (toc) space than "x.txt". Will you ever notice it, no!
As far as the "USE" keyword, this just sets the context for you, so you dont have to fully qualify object names. The "USE" keyword is NOT sql, you cannot use in in another application (like a vb/c# app) or within a stored procedure but it is like the "GO" keyword in that it tells SSMS to do something, change the context.

error invoking procedure with multiple select commands

I have an SSIS package with a data flow task. The OLE DB source has an execute proc statement. It fails while saving with below error message.
an OLEDB record is available... The metadata could not be determined because the statement 'select appname....' in procedure is not compatible with the statement 'select appid....' in procedure
This proc has several select statements and returns the appropriate result set as per parameters passed. Any pointers to bypass this error?
So you're saying that the SP will return different meta data depending on the parameter passed? SSIS doesn't like this - it can't update the meta data dynamically at run time. i.e. if you create a package that splits or sorts on a certain column, then you run the SP and it doesn't return that column, or the same column is a different data type, what should SSIS do? It can't automatically work it out.
I suggest you create a data source for each possibility of result set returned and conditionally execute each on as required.
In short SP's returning optionally different datasets is often not a good idea, definitely not from an ETL perspective.
Here is some code that shows how to create dynamically built output, (you could use the same method with just one output), but you'll still face the same problems downstream.
http://www.codeproject.com/Articles/32151/How-to-Use-a-Multi-Result-Set-Stored-Procedure-in
I ran into this issue as well. In my case, the result returned looked identical no matter which branch was executed, the difference was just in how that result was obtained (including different source tables). I simply executed all the cases with a union, and each "where" clause included the conditions for its execution instead of using "if" logic to choose a query.

Different SELECT statement from what I was familiar with

Why are these statements valid [am Using SQL2008 R2]
Select* FROM TableName --UPDATE: this is not allowed in Oracle (10g)
and
Select *From TableName --UPDATE: this is allowed in Oracle (10g)
Now this
Select*From TableName --UPDATE: this is not allowed in Oracle (10g)
UPDATE: All three are allowed in SQL Server
I have known it this way Select * From TableName
The spaces are not required in these instances to recognize the distinct tokens of the statement.
In general, programming language parsers work by breaking text into distinct tokens. In SQL Server in this instance, the keyword search completes at "select" since you cannot have keywords with a *. The * gets put into the next token.
You can even do this (look no space). Ugly as it may be
select*from[master]..[spt_values]where[type]='p'
Are you asking the reason they are valid or why they are able to perform the operations that you needed i.e. listing all contents- both field, records, and data of a named database- entire named database structure? The reason is that SQL understands, and takes note of its keywords or its inbuilt commands, in as much as you spelt the command words right, it doesnt matter where you place character such as , it will always work, and the commands will be executed. In as much as the syntax and the structure of the command is complete e.g. SELECT command is complete when you have- SELECT (what()) FROM (where(tablename));
If ou want you may add the WHERE command too like: SELECT (what(*)) FROM (where(tablename)) WHERE (condition); it doesnt matter the space inbetween each inbuilt commands or keywords related to SQL.

Resources