No IntelliSense in SSMS 2008 for Table Valued Function - sql

I'm building a Table Valued Function in SSMS, and I'm expecting IntelliSense to help me select columns, but it doesn't. Consider this:
CREATE FUNCTION dbo.My_TVF
(
)
RETURNS TABLE
AS
RETURN
(
SELECT [PO].I -- Here I is my cursor, ctrl+space does nothing
FROM dbo.SomePurchaseOrderView PO
JOIN dbo.SomePurchaseOrderLineView POL ON PO.PO_NUM = POL.PO_NUM
WHERE PO.PO_NUM IN (
SELECT TOP 500 PO_NUM
FROM dbo.SomeTable
WHERE PROCESSED = 0
)
)
GO
I want it to suggest column names for the select clause.
Notes:
The cache is fresh (CTRL + SHIFT + R)
IntelliSense works fine in general, this is the only situation I've encountered where it doesn't.
I'm querying a view instead of a table, if it matters.
I know it often fails when there is some kind of syntax error in what you are writing, but I can execute my query just fine when I specify a column.

On msdn it says: "IntelliSense is available for the SELECT statement when it is coded by itself, but not when the SELECT is contained in a CREATE FUNCTION statement."
Although, when testing it in my SSMS 2012, it does seem to work...
Source: http://msdn.microsoft.com/en-us/library/bb934481.aspx
(sorry, I don't have enough rep for a comment...)

I have found a blog posted by Pinal Dave on SQL Server Authority related intellisense.
Here's the link:
http://blog.sqlauthority.com/2009/03/31/sql-server-2008-intellisense-does-not-work-enable-intellisense/
Follow the below steps from the blog:
1) Make sure you are connected to SQL Server 2008 Edition.
2) IntelliSense should be enabled.
a) From Toolbar
b) Go to Tools >> Options >> Text Editor >> Transact-SQL >> IntelliSense
3) IntelliSense should be refreshed with the latest changes in database.
a) Press CTRL+SHIFT+R
b) Go to Edit >> IntelliSense >> Refresh Local Cache
4) Go to Tools >> Options >> Text Editor >> Transact-SQL >> General >> IntelliSense

Here are few assumptions:
You are connected to the right SQL Server that has the tables listed in query below.
You are not using index hints. I have had problems with intellisense and index hints.
I was able to reproduce the problem on my computer, looks like you need to type a comma before SSMS will suggest the next column.
CREATE FUNCTION dbo.My_TVF
(
)
RETURNS TABLE
AS
RETURN
(
SELECT [PO].I X -- If you press ctrl+space at the location of X it does nothing
-- since it has already suggested that column, PO.I (that's my assumption)
-- for next columns type a comma after PO.I and press ctrl+space.
-- I had no problems getting suggestions for other columns.
FROM dbo.SomePurchaseOrderVIEW PO
JOIN dbo.SomePurchaseOrderLineView POL ON PO.PO_NUM = POL.PO_NUM
WHERE PO.PO_NUM IN (
SELECT TOP 500 PO_NUM
FROM dbo.SomeTable
WHERE PROCESSED = 0
)
)
GO

Related

Excel parameters from SQL Query from ODBC "Error - No Value given for one or more required parameters when using question mark `WHERE XXX = ?`

I have an Excel file with an SQLOLEDB connection to a MS SQL server,
When I do this with an Oracle link I can simply put WHERE XXX = ? in my query to prompt for values in Excel, however doing it with MSSQL I am getting the following error:
No Value given for one or more required parameters
When trying to parameterise a basic excel query from a value to ?
If i use values like this I get results:
SELECT *
FROM srv.stats
WHERE srv.stats.[year] = '2016'
AND srv.stats.[quarter] = '1'
When I add in the parameter ? I get the above error.
SELECT *
FROM srv.stats
WHERE srv.stats.[year] = ?
AND srv.stats.[quarter] = ?
I want to be able to do this without using VB.
Since MS SQL sources from ODBC connections don't inherently allow you to use the WHERE xxx = ? code in your SQL query (unlike Oracle connections) you need to spoof Excel to allow parameters from a MS SQL data source by building a Microsoft Query and then overwriting it.
Open a new Excel file and go to the Data tab, choose the From Other Sources drop down and select From Microsoft Query.
The Choose Data Source window will appear. Choose an existing datasource or set up a new connection to your server by selecting <New Data Source> and click OK.
Once done you will see the query wizard window open to select tables and columns, as you're going to be adding your own SQL query later just select one table that is in your query and add it to the Columns in your query: section by using the > button. For the next 2 windows just click Next and then finally Finish.
You will then be prompted to select how you want to view the data in the Import Data window, first of all click the Properties... button.
And then the Definition tab, in the Command text: box you will have a SELECT statement, below there you will need to add WHERE clauses for the amount you have in your actual query. These need to be added in the format of:
WHERE 1 = ?
AND 2 = ?
AND 3 = ?
Once this is done click OK to go back to the Import Data window and select your output type; Table, PivotTable report or PivotChart and PivotTable Report depending on what how you want to display your data.
You will then be prompted to enter a value for each parameter. If you are getting these values from Cells choose the location of them now in the order you will be putting in your actual parameters. When you have entered your parameter sources go back to the Data tab and click connections and then into the definition tab.
Now in the Command text: box paste in your actual SQL query with your parameters in the WHERE clause = ? and in the same order your defined the sources and click OK, Your data should now populate as it usually does with your parameters being used.
There is no way to prompt for inputs directly in SQL Server in the same way that you can in Access for example. You can make the values that are passed into queries like this.
DECLARE #year SMALLINT
SET #year = 2016
DECLARE #quarter TINYINT
SET #quarter = 1
SELECT *
FROM srv.stats
WHERE srv.stats.[year] = #year
AND srv.stats.[quarter] = #quarter;
You then just need to find a way that suits your solution (Excel?) to pass these. This might, for example, take the form of a stored procedure.
CREATE PROCEDURE testProcedure #year SMALLINT, #quarter TINYINT
AS
SELECT *
FROM srv.stats
WHERE srv.stats.[year] = #year
AND srv.stats.[quarter] = #quarter
GO;

Table aliases and field names with spaces

From SAS, I am updating a table in MS Access with values from another table. Some of the fields in the table being updated contain spaces. This seems to be causing problems in the update statement. This gives me the error "Too few parameters. Expected 1.":
update [Original Table] as a inner join Updates as b on a.ID = b.ID
set a.[Variable 1] = b.[Variable 1]
where Year = "2000";
For field names without spaces, the statement works without error. And since I am using the field names elsewhere without table references/aliases, I figure the combination of [] and aliases is causing the problem. Any suggestions to address this?
Year() is a function which returns a variant subtype integer which corresponds to the calendar year of the date value you give to the function.
In your case, it seems you have a field named Year. So perhaps the "missing parameter" is the expected date argument to the Year() function.
You can avoid confusing the db engine by enclosing Year in square brackets. The brackets signal the engine that Year is an object (field) name instead of the function.
update [Original Table] as a inner join Updates as b on a.ID = b.ID
set a.[Variable 1] = b.[Variable 1]
where [Year] = "2000";
Whenever possible, it's better to use names which don't conflict with reserved words. That may not be practical in your situation ... but if you can do it you will reduce the number of Access development headaches you will suffer. :-)
For further information about "naming challenges", see Problem names and reserved words in Access.
Sorry I overlooked the point that the query can work in spite of that WHERE clause issue.
I can't see anything about the remainder of your SQL which should trigger a complaint from the db engine. I assume you tested that statement directly in Access, and got no errors.
If there is something peculiar to the interaction between SAS and Access which causes this, perhaps you could use a saved Access query as a work-around. Take that SQL and save it as a named query, qrySasTest, in your Access db. Then try executing qrySasTest from the SAS side.
This query worked as is for me (modifying only table names), both run from access and run from SAS. This is with SAS 9.3 64 bit and Office 2010 64 bit, so I suppose there could be something different going on with your version(s) of both, but it worked as expected.
proc sql;
connect to access (path="c:\temp\test.accdb");
execute
(
update [Test2] as a inner join Test as b on a.ID = b.ID
set a.[Variable 1] = b.[Variable 1]
where Year ="2000";
)
by access;
disconnect from access;
quit;
If you want to use the libname reference instead of SAS access, you can use the "dquote=ansi" option after your proc sql statement as shown below. In this example I created a library reference called mydbms:
libname mydbms odbc dsn=prompt preserve_names=yes;
proc sql dquote=ansi;
update mydbms."Original Table" as a inner join mydbms.Updates as b on a.ID = b.ID
set a."Variable 1" = b."Variable 1"
where Year = "2000";
quit;

Create an insert script from select results

Using SQL Server Management Studio is there a way I can select one or more rows in the grid of select results and have SQL Server Mangement Studio generate one or more insert statements (one for each row selected) which would insert that data into a table with the same schema?
Edit: I know how to create one manually, but I was hoping there would be something that would create it automatically for me. If you are familiar with Toad there is a way to have Toad generate inserts based on data in the results pane and I was hoping SSMS had an equivalant function.
Try to save the query result into a disposable table.
For example:
SELECT * INTO disposable_customer_table FROM customer_table WHERE id IN (in range of something)
Then do a db -> Tasks -> Generate Scripts.
Select specific database objects.
Choose disposable_customer_table from the list of table names.
Choose Save to file.
Make sure to do an Advance setup and select "Data only" from the 'Types of data to script'.
Tweak the result file and rename the disposable_customer_table back to the original table name.
Clean it up and drop the disposable_customer_table.
select 'insert into tableB values (', tableA.x ,',',tableA.y,',',tableA.z,')' from tableA
I think you have two options here:
Create your inserts manually. For instance:
select Name, Surname,
'insert into Person (Name,surname) values ('''+Name+''','''+Surname+')'
from Person
This gets you the results and, in the last column, the insert script for the row. You can then select and paste it in an Editor window.
Right click on the db -> Tasks -> Generate Scripts. Press then Advance and select "Data Only" (Default is Schema Only).
Perform your query and right click on the blank area where the column headers meet the row number in the Results view.
You can then select Script Grid Results:

Getting list of table comments in PostgreSQL

Postgresql allows adding comments to objects such as tables. For example I've added a comment to table "mytable" by using this SQL command:
COMMENT ON TABLE mytable IS 'This is my table.';
My question is:
If I want to use a SQL-command to get all tables along with their respective comment - how would I do this? What would be the appropriate query for this?
Thanks in advance!
Cheers!
All comments are stored in pg_description
To get the comments on a table, you need to join it to pg_class
As an alternative you can also use the function obj_description() to retrieve this information:
SELECT obj_description(oid)
FROM pg_class
WHERE relkind = 'r'
Edit
In psql you can simply use the \d+ command to show all tables including their comments. Or use the \dd command to show all comments in the system
The main problem with "show comments" is to remember the name of specific fucntions, catalog names, etc. to retrieve the comment... Or its pages on the Guide. At this answer we solve in 2 ways: by a summary of the ordinary way (the pg-way) to show comments; and by offering shortcut functions, to reduce the "remember problem".
The pg-way
The simplest, on psql, is to use \dt+ to show table comments and \d+ to show column comments. Some for function comments?
To get on SQL, and for people that remember all parameters, the pg-way is to use the obj_description() function (Guide) in conjunction with adequate reg-type:
Function: select obj_description('mySchema.myFunction'::regproc, 'pg_proc')
Table or View: ("... and most everything else that has columns or is otherwise similar to a table",guide) select obj_description('mySchema.myClass'::regclass, 'pg_class')
other generic: select obj_description('mySchema.myObject'::regName, pg_regName), where regName is 1 in 10 of datatype-oid references Guide, and pg_regName is the same replacing prefix reg by prefix pg_.
other specific: similar select obj_description('schema.myObject'::regName, catalog_name), where catalog_name is to be more specific about a (1 in 95) key-word at catalogs Guide. It can reduce some "namespace pollution". For example pg_proc for functions, pg_aggregate for aggregate functions.
to get comment for a shared database object, analog but using the function shobj_description() (same page Guide).
Column: select col_description('mySchema.myObject'::regClass, column_number), where column_number is the column's ordinal position (at the CREATE TABLE). No column-name... See col_description(table,column_name) complement bellow.
IMPORTANT: the use of same reg-type and _catalog_name_ (e. g. ::regclass and pg_class) seems redundant and sometimes obj_description('obj'::regObj) works fine, with only reg-type! ...But, as the Guide say:
it is deprecated since there is no guarantee that OIDs are unique across different system catalogs; therefore, the wrong comment might be returned.
Shortcut functions to get comments
if you are finding it difficult to remember all the type-casts and parameters, the best is to adopt a new and simplest function to retrieve comments.
CREATE FUNCTION rel_description(
p_relname text, p_schemaname text DEFAULT NULL
) RETURNS text AS $f$
SELECT obj_description((CASE
WHEN strpos($1, '.')>0 THEN $1
WHEN $2 IS NULL THEN 'public.'||$1
ELSE $2||'.'||$1
END)::regclass, 'pg_class');
$f$ LANGUAGE SQL;
-- EXAMPLES OF USE:
-- SELECT rel_description('mytable');
-- SELECT rel_description('public.mytable');
-- SELECT rel_description('otherschema.mytable');
-- SELECT rel_description('mytable', 'otherschema');
-- PS: rel_description('public.mytable', 'otherschema') is a syntax error,
-- but not generates exception: returns the same as ('public.mytable')
We need also something less ugly to show column comments. There are no kind of pg_get_serial_sequence() function to get ordinal position of a column from its name. The native col_description('mySchema.myObject'::regClass, column_number) needs a complement:
CREATE FUNCTION col_description(
p_relname text, -- table name or schema.table
p_colname text, -- table's column name
p_database text DEFAULT NULL -- NULL for current
) RETURNS text AS $f$
WITH r AS (
SELECT CASE WHEN array_length(x,1)=1 THEN array['public',x[1]] ELSE x END
FROM regexp_split_to_array(p_relname,'\.') t(x)
)
SELECT col_description(p_relname::regClass, ordinal_position)
FROM r, information_schema.columns i
WHERE i.table_catalog = CASE
WHEN $3 IS NULL THEN current_database() ELSE $3
END and i.table_schema = r.x[1]
and i.table_name = r.x[2]
and i.column_name = p_colname
$f$ LANGUAGE SQL;
-- SELECT col_description('tableName','colName');
-- SELECT col_description('schemaName.tableName','colName','databaseName);
NOTES:
As recommended by this answer: "If you want to know which queries does psql run when you do \dt+ or \d+ customers, just launche it with psql -E".
It is possible to express multiline comment, using any multiline string (with E\n or $$...$$)... But you can't apply trim() or use another dynamic aspect. Must use dynamic SQL on COMMENT clause for it.
No comments to see? PostgreSQL programmers not use COMMENT clause because it is ugly to use: there are no syntax to add comment on CREATE TABLE or on CREATE FUNCTION; and there are no good IDE to automatize it.
The modern http://postgREST.org/ interface show comments on the Web!
You can use pg_catalog.obj_description function and information_schema.tables schema view:
SELECT t.table_name, pg_catalog.obj_description(pgc.oid, 'pg_class')
FROM information_schema.tables t
INNER JOIN pg_catalog.pg_class pgc
ON t.table_name = pgc.relname
WHERE t.table_type='BASE TABLE'
AND t.table_schema='public';
FUNCTIONS-INFO-COMMENT-TABLE
INFORMATION_SCHEMA Support in MySQL, PostgreSQL
If you still have tables with mixed case names you can use the following to get a complete list of all tables in a database with their comment, as well as catalog, schema, table type, etc. (tested in PostGIS - pgAdmin 4):
select *,
obj_description((table_schema||'.'||quote_ident(table_name))::regclass)
from information_schema.tables where table_schema <> 'pg_catalog'

SQL Server 2008 column select

In SQL Server, if I got a table with like 20 columns and I want 18 of them, can I say something like * minus columnname1, columnname2, course right now I write them all.
But if you could it would be much easier.
Little hint to replace the asterisk with column names in SQL Management Studio in no time without any fancy plugin:
Select your written query (no matter how many joins, etc.)
Right click and select "Design Query in Editor..."
Simply click "Ok"
The asterisk should have been expanded to column names now :)
Ofc it's possible to select/deselect any column in the query editor..
Hth
It is not possible. However if you are using SQL Server Management Studio 2008 / 2005 you can right click on the table and select the "Script Table as > SELECT To" menu option. This will save you typing the column names, or purchase Red-Gate's SQL Prompt
Out of the box - no, it's not possible. You have to spell out all the columns you want explicitly.
With SQL Server Management Studio 2008, there is intellisense which can help you select columns from a table - so that's certainly one step to help ease the pain.
Add-in tools like SQL Prompt offer more help - in SQL Prompt, you can type
SELECT *
FROM dbo.YourTable
and if you have the cursor just after the asterisk symbol (*), you can press <TAB> and expand the asterisk into the list of all columns for that table (and then remove the two you don't want) - or you can popup a window and pick those columns you really want.
Very handy, very useful, very much speeding up development - but it's not a free tool.....
You can use select TOP (18) * from givenTable is you want 18 rows.
There is no such method for columns. In fact column names are stored in master db and you can extract them and consruct query looking like what you are asking for BUT it would not be easier than just select field1,field2 ... field18 from blaBlaBla.
SELECT table_name=sysobjects.name,
column_name=syscolumns.name,
datatype=systypes.name,
length=syscolumns.length
FROM sysobjects
JOIN syscolumns ON sysobjects.id = syscolumns.id
JOIN systypes ON syscolumns.xtype=systypes.xtype
WHERE sysobjects.xtype='U'
and sysobjects.name='myTableName'
ORDER BY sysobjects.name,syscolumns.colid
will give you the list of your columns. You can write select generator based on this query.
I'd like to add to the answer of, "No, it's not possible directly in SQL". I would love to have that feature too! It sucks when you're trying to do some quick debugging on a 10+ column table that has a varbinary(max).
But I really just want to point out an alternative to Kane's tip for SSMS 2008 (Sql Server Management Studio).
If you open the Object Explorer (right-click in the query window and choose "Open Server in Object Explorer"), navigate to the node for the table in question. Expand the node so you can see the "Columns" node. Now "drag" the Columns node over to your query window and "drop" it. It will paste in all the column names for the table--and you can use it directly in a SELECT clause.
It is not possible as far as I know.
I have created a script for easy copy/pasting multiple columns, you might find it useful. See:
http://www.sqlservercentral.com/scripts/102375/
The script is explained in detail there, but in short for those who do not have an account on sqlservercentral:
It's a stored procedure that i can run using a shortcut. Type in your tablename (also works with temp tables and views), highlight it, hit the shortcut and it will display the columns of the table. From there you can easily copy multiple columns (the columns are also shown with a comma in front of the column name, so that also saves you some typing) and paste it in your query screen.
CREATE PROCEDURE [dbo].[sp_ColumnSelect]
#FullObjectName varchar(200)
AS
/*
Author: Robin van Schaik
Version: 1.3 (03-OCT-2012)
*/
DECLARE #Object varchar(200)
DECLARE #Schema varchar(200)
DECLARE #Database varchar(200)
DECLARE #IsTempTable bit
-- Break down parameter in Database/Schema/Object
SET #Object = PARSENAME(#FullObjectName,1)
SET #Schema = ISNULL(PARSENAME(#FullObjectName,2),'dbo')
SET #IsTempTable = case when left(#Object,1)='#' then 1 else 0 end
SET #Database = case when #IsTempTable=1 then 'tempdb' else PARSENAME(#FullObjectName,3) end
EXEC(
'SELECT
b.Name as ColumnStart
, '',''+b.Name as ColumnNext
, ''[''+b.Name+'']'' as ColumnStartBr
, '',[''+b.Name+'']'' as ColumnNextBr
FROM
' +#Database+'.sys.objects a
INNER JOIN
' +#Database+'.sys.columns b
ON a.object_id=b.object_id
INNER JOIN
' +#Database+'.sys.schemas d
ON a.schema_id=d.schema_id
WHERE
a.Object_ID=OBJECT_ID('''+#Database+'.'+#Schema+'.'+#Object+''')
AND d.name = '''+#Schema+'''
'
)