When are square brackets not to be used? - sql-server

I understand that square brackets allow the use of reserved names or previously disallowed characters such as spaces in your identifiers. I thought adding them everywhere was good practice. (See What is the use of the square brackets [] in sql statements?)
However, I notice that when I use them in the COL_LENGTH function, I get some unexpected results:
SELECT COL_LENGTH(N'[TestTable]', N'[RatingID]') -- Returns NULL
SELECT COL_LENGTH(N'TestTable', N'[RatingID]') -- Returns NULL
SELECT COL_LENGTH(N'[TestTable]', N'RatingID') -- Returns 10
SELECT COL_LENGTH(N'TestTable', N'RatingID') -- Returns 10
I can see that by defining the column name in single quotes, the square brackets become redundant, but I don't understand why they break the call. That square brackets work for the table argument increases my confusion.
Is there a rule for when square brackets shouldn't be used?

Do not pass square brackets into functions that take strings only use in actual SQL statements. The function is looking for a table with the name including the square brackets.

Related

QUOTENAME() with parenthesis, curly brackets, angle brackets, or grave accents

While reading the documentation for QUOTENAME(), I see that it supports a variety of delimiter characters:
Square brackets - [] (default)
Parenthesis - ()
Curly brackets - {}
Angle brackets - <>
Single quotes - '
Double quotes - "
Grave accents - `
In addition to wrapping the content in opening and closing delimiters, QUOTENAME() appears to double up any contained characters that match the closing delimiter. For example: QUOTENAME('matrix[2][3]') yields [matrix[2]][3]]] and QUOTENAME('cell(2)(3)', '(') yields (cell(2))(3))).
While I understand the usage of single quotes, double quotes, and square brackets to delimit identifiers and text values (primarily when constructing dynamic SQL), I am not sure what use the other forms might have.
Are there any places in SQL Server syntax where parenthesis, curly bracket, angle bracket, or grave accent delimited content has any special meaning? Are there any languages (XML, JSON, etc.) outside of SQL where those other forms might be useful? Such cases would have to recognize the doubled character as an escape.
This is more a question of interest rather than a particular problem that I am trying to solve.

How can I use a variable in a T-SQL partition function?

I'm confused about the definition for boundary_values in the Microsoft documentation as related to constants and expressions.
I have created partitioned tables in MSSQL, so I know how to set the values for the "partition functions". I also have a stored procedure that updates the boundary values for two partition functions every month, so I know how to programmatically create the functions.
But I recently re-read the documentation for CREATE PARTITION FUNCTION. The syntax is:
CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type )
AS RANGE [ LEFT | RIGHT ]
FOR VALUES ( [ *boundary_value* [ ,...n ] ] )
The explanation has these sentences that baffle me:
boundary_value is a constant expression that can reference variables. This includes user-defined type variables, or functions and user-defined functions. It cannot reference Transact-SQL expressions.
How can a constant expression "reference" a variable? According to the doc on expressions, a constant expression is "a symbol that represents a single, specific data value. For more information, see Constants (Transact-SQL).". That link says that a character constant, for example, is just some stuff between quote marks. Numeric constants are just a single number. This says that variables can't be used in a constant expression -- that would be a Transact-SQL expression.
And the "functions and user-defined functions" phrase also baffles me.
There are lots of examples of how to programmatically build boundary values, especially when working with dates, but they just programmatically make one large SQL expression using Create Partition Function and appending the boundary values (usually in a loop). That's not setting the boundary_value to a constant expression that's "referencing" a "variable". And it's not using functions. I have seen no examples that would illuminate how to reference a variable, or use a function, in the boundary_value.
Does anyone understand what this is trying to say?

SQL [int] versus int

Recently I am working with SQL language. I found two ways of declaring temporary table variables(starting with #). My question is:
Is there any difference between them?
DECLARE
#variable1 [int],
#variable2 int
There is no difference in this instance. However, the square brackets are used as delimiters if you have special characters that need identifying - for example if you name a column "First Name", you'll need square brackets to escape the space character.
Nope those are the same. Typing it with the brackets is just extra keystrokes.

Extra rows for custom expression to display "filtered" sum

So I have a table that gets its resultset from a procedure and everything looks great, including the totals at the bottom. The user has asked for a few custom rows at the bottom that are only to represent the totals for specific criteria or group. Say you have a field called AuctionPrice. In the dataset it is from an aggregate within a sql procedure.
If I place an extra row at the bottom of the table and the "AuctionPrice" field, I use an expression like this
=SUM(IIF(Fields!AuctionPrice > 0, Fields!AuctionPrice, 0))
This produced an error, whereas an expression with using a different field in the comparision works fine.
Is it true that you can not use an expression using a field that is already included in an aggregate (sum) in the dataset?
For the ssrs expression to work you forgot to define .value after your field
The correct expression must be like the one below
=SUM(IIF(Fields!AuctionPrice.value > 0, Fields!AuctionPrice.value, 0))
It is because the Fields!AuctionPrice column has special character(!) in it. You need to escape it using square bracket
select SUM(IIF([Fields!AuctionPrice] > 0, [Fields!AuctionPrice], 0))
From yourtable
Rules for Regular Identifiers
The names of variables, functions, and stored procedures must comply with the following rules for Transact-SQL identifiers.
The first character must be one of the following:
A letter as defined by the Unicode Standard 3.2. The Unicode definition of letters includes Latin characters from a through z,
from A through Z, and also letter characters from other languages.
The underscore (_), at sign (#), or number sign (#).
Certain symbols at the beginning of an identifier have special meaning in SQL Server. A regular identifier that starts with the at sign always denotes a local variable or parameter and cannot be used as the name of any other type of object. An identifier that starts with a number sign denotes a temporary table or procedure. An identifier that starts with double number signs (##) denotes a global temporary object. Although the number sign or double number sign characters can be used to begin the names of other types of objects, we do not recommend this practice.
Some Transact-SQL functions have names that start with double at signs (##). To avoid confusion with these functions, you should not use names that start with ##.
Subsequent characters can include the following:
Letters as defined in the Unicode Standard 3.2.
Decimal numbers from either Basic Latin or other national scripts.
The at sign, dollar sign ($), number sign,
or underscore.
The identifier must not be a Transact-SQL reserved word. SQL Server reserves both the uppercase and lowercase versions of reserved words. When identifiers are used in Transact-SQL statements, the identifiers that do not comply with these rules must be delimited by double quotation marks or brackets. The words that are reserved depend on the database compatibility level. This level can be set by using the ALTER DATABASE statement.
Embedded spaces or special characters are not allowed.
Supplementary characters are not allowed.
When identifiers are used in Transact-SQL statements, the identifiers that do not comply with these rules must be delimited by double quotation marks or brackets.

Selecting arrays in nicely printed format in SQL

I'm trying to select for a two dimensional array of integers, and directing the output to a file. Is there any way that I can write a postgresql statement that would make the output of the select statement nicely formatted. As in each array of integers that is an element of the 2D array is on its own line.
Right now I just get this output:
SELECT array FROM table LIMIT 1;
{{0,0,0},{1,1,1},{2,2,2},{3,3,3},{0,0,0},{1,1,1},{2,2,2},{3,3,3}
,{0,0,0},{1,1,1},{2,2,2},{3,3,3},{0,0,0},{1,1,1},{2,2,2},{3,3,3}
,{0,0,0},{1,1,1},{2,2,2},{3,3,3},{0,0,0},{1,1,1},{2,2,2},{3,3,3}}
And I would like to get something more like this:
{0,0,0}
{1,1,1}
{2,2,2}
...
I can do this after the query returns with some parsing, but if its possible to do it in Postgres itself that would be ideal.
There are several ways. One way is to cast the array to text and split it up with regexp_split_to_table().
This function is present in PostgreSQL 8.3 or later.
SELECT regexp_split_to_table(trim(my_2d_intarr::text, '{}'), '},{');
Output:
0,0,0
1,1,1
2,2,2
If you want the enclosing brackets (maybe you don't?), add them back like this:
SELECT '{' || regexp_split_to_table(trim(my_2d_intarr::text, '{}'), '},{') || '}';
Ourtput:
{0,0,0}
{1,1,1}
{2,2,2}
Alternative:
This should also work with PostgreSQL 8.2 or maybe even earlier, but I did not test that.
SELECT my_2d_int_arr_var[x:x][1:3]
FROM (SELECT generate_series(1, array_upper(my_2d_intarr, 1), 1)::int4 AS x)) x
Output:
{{0,0,0}}
{{1,1,1}}
{{2,2,2}}
(You may want to strip some curly brackets ..)
Else, I would write a plpgsql function that loops through the array. Fairly easy.
There is also the related unnest() function, but it returns a row per base element (integer in this case), so it's no use here.
One (fast!) way to output the result: COPY.

Resources