SSRS Expression to Switch LastName, FirstName to FirstName LastName in field - sql-server

SQL Server 2016
SSRS 2016
IDE Visual Studio 2017
Problem: Report Field contains value of Doe, John
Solution/Output: Using SSRS expression require field to output John Doe
Current sample of my expression that gives me an #error when I run preview:
=Split(Fields!Name.Value,",")(1).ToString() &","& Split(Fields!Name.Value,",")(0).ToString()
I found example above online, however throws an error. Relatively new to SSRS advanced expressions.
I don't have the option to edit the T-SQL query

This should work...
=SWITCH(
split(Fields!Name.Value, ",").length = 1, Fields!Name.Value,
True, TRIM(split(Fields!Name.Value + ",", ",")(1))
+ " "
+ TRIM(split(Fields!Name.Value + ",", ",")(0))
)
What I've done here is...
for the first SWITCH expression pair, check if the name has only a single element, if it does return the name (e.g. for "not Applicable". This method is safer as it will handle anything with no commas present.
The second part True just acts like an ELSE
In this case I've added a comma to the end of the Name field value so that the evaluated string always has at least 1 comma (thus preventing the error). I've also trimmed the results so you don't get unwanted spaces.
We now get these results

Related

SQL Server - REPLACE - Matching string with old substring edits entire field?

I recently had a request come through to remove some Agent names from the guest surname field in a client's database.
Eg. 'John Smith -Wotif'
When testing using the following UPDATE statement, the entire field was wiped rather than just the specific string.
UPDATE GUEST
SET SURNAME = REPLACE(' -Wotif',' -Wotif','')
WHERE SURNAME LIKE '% -Wotif'
I've since found that simply using the column name as the matching string will allow the full statement to work (even if already specified in the SET section), but I can't work out where the logic of the original statement effectively says 'wipe these fields entirely'.
Unless specified otherwise, surely the '' replacement only applies to the value contained within the substring, regardless of whether the string and substring match?
The first argument in the REPLACE function is the full string that you want to search. So you should be referencing the SURNAME field rather than specifying part of the string.
REPLACE(SURNAME,' -Wotif','')
You update SQL command should be like this -
UPDATE GUEST
SET SURNAME = REPLACE(SURNAME, 'FindValue' , 'ReplaceWithValue')
WHERE SURNAME LIKE '% -Wotif'
If you want to find & replace '-Wotif' with blank, then update command should be like below-
UPDATE GUEST
SET SURNAME = REPLACE(SURNAME, '-Wotif' , '')
WHERE SURNAME LIKE '% -Wotif'

Formatting data that also contains null values in MS Report Builder

Running SQL Server 2012 Report Builder 3.0. I have a dataset that has a Phone Number which occasionally has Null values. Data obtained using a subquery in my Select statement like this: CellPhone = (select top 1 cp.PhoneNumber from providers.ProviderPhones cp where cp.ProviderID = prv.ProviderID and cp.PhoneTypeID = 24 order by PhoneID desc) This returns the phone as 1234567890.
The following expression works to format the phone number as nnn-nnn-nnnn:
=left(str(Fields!cellPhone.Value),4) + "-" + mid(str(Fields!cellPhone.Value),4,3) + "-" + right(str(Fields!cellPhone.Value),4)
But when there are nulls, I get #ERROR
So to handle the nulls I tried the following:
=IIf(Fields!cellPhone.Value Is Nothing,"No Value", left(str(Fields!cellPhone.Value),4) + "-" + mid(str(Fields!cellPhone.Value),4,3) + "-" + right(str(Fields!cellPhone.Value),4))
This gives me the same results as above. So then I simplified the expression just to test it:
=IIf(Fields!cellPhone.Value Is Nothing,"No Value", Fields!cellPhone.Value)
Which gives me "No Value" when there is a Null and a non formatted phone number.
Why can't I combine the formatting portion with the Is Nothing test? Or is there a better way to format the phone number? (I tried using the same formatting expression as a Custom Format which removed the nulls but didn't format the phone number). Thanks.

cdbflite Use /filter to find empty lines

I have a file user.dbf, I want to filter all mail that are empty, I searched on the internet to find a way to filter the empty field but without success.
user.dbf : id ; username ; password ; mail
Using the cdbflite software, I tried to use this command :
cdbflite.exe user.dbf /filter:mail=' ' /select:id,username > log.csv
but it return : Invalid Filter
Help me please :'(
Excerpted from http://www.whitetown.com/cdbflite/cl/
/filter:condition
/f:condition
Installation of the filter. The filter allows to select of some
records which satisfying to some condition. Allowable to use several
conditions in one filter and/or some filters. In the latter case they
was united as condition 'AND'. For example:
/filter:name=Smith - to select people with name "Smith"
/filter:name=Smith&age>30 - to select people with name "Smith" and
age more them 30 year
/filter:name=Smith&age{30 - to select people with name "Smith" and
age less them 30 year
/filter:name=Smith;name=Gates - to select people with name "Smith" or
"Gates"
/filter:name=Smith|name=Gates - to select people with name "Smith" or
"Gates"
/filter:name~uck - to select people, containing a substring "uck".
/filter:name=A /filter:age=30 - it's same as
/filter:name=A&age=30
If the compared expression contains blanks, you should to conclude
expression in quotes.
/filter:name="John Smith"
As a guess, try using double quotes and try having no space between them:
/filter:mail=""
If that doesn't work, I don't think it's possible.

SQL Server 2014 - XQuery - get comma-separated List

I have a database table in SQL Server 2014 with only an ID column (int) and a column xmldata of type XML.
This xmldata column contains for example:
<book>
<title>a nice Novel</title>
<author>Maria</author>
<author>Peter</author>
</book>
As expected, I have multiple books, therefore multiple rows with xmldata.
I now want to execute a query for all books, where Peter is an Author. I tried this in some xPath2.0 testers and got to the conclusion that:
/book/author/concat(text(), if(position() != last())then ',' else '')
works.
If you try to port this success into SQL Server 2014 Express it looks like this, which is correctly escaped syntax etc.:
SELECT id
FROM books
WHERE 'Peter' IN (xmldata.query('/book/author/concat(text(), if(position() != last())then '','' else '''')'))
SQL Server however does not seem to support a construction like /concat(...) because of:
The XQuery syntax '/function()' is not supported.
I am at a loss then however, why /text() would work in:
SELECT id, xmldata.query('/book/author/text()')
FROM books
which it does.
My constraints:
I am bound to use SQL Server
I am bound to xpath or something else that can be "injected" as the statement above (if the structure of the xml or the database changes, the xpath above could be changed isolated and the application logic above that constructs the Where clause will not be touched) SEE EDIT
Is there a way to make this work?
regards,
BillDoor
EDIT:
My second constraint boils down to this:
An Application constructs the Where clause by
expression <operator> value(s)
expression is stored in a database and is mapped by the xmlTag eg.:
| tokenname| querystring
| "author" | "xmldata.query(/book/author/text())"
the values are presented by the Requesting user. so if the user asks for the author "Peter" with operator "EQUALS" the application constructs:
xmaldata.query(/book/author/text()) = "Peter"
as where clause.
If the customer now decides that author needs to be nested in an <authors> element, i can simply change the expression in the construction-database and the whole machine keeps running without any changes to code, simply manageable.
So i need a way to achieve that
<xPath> <operator> "Peter"
or any other combination of this three isolated components (see above: "Peter" IN <xPath>...) gets me all of Peters' books, even if there are multiple unsorted authors.
This would not suffice either (its not sqlserver syntax, but you get the idea):
WHERE xmldata.exist('/dossier/client[text() = "$1"]', "Peter") = 1;
because the operator is still nested in the expression, i could not request <> "Peter".
I know this is strange, please don't question the concept as a whole - it has a history :/
EDIT: further clarification:
The filter-rules come into the app in an XML structure basically:
Operator: "EQ"
field: "name"
value "Peter"
evaluates to:
expression = lookupExpressionForField("name") --> "table2.xmldata.value('book/author/name[1]', 'varchar')"
operator = lookUpOperatorMapping("EQ") --> "="
value = FormatValues("Peter") --> "Peter" (if multiple values are passed FormatValues cosntructs a comma seperated list)
the application then builds:
- constructClause(String expression,String operator,String value)
"table2.xmldata.value('book/author/name[1]', 'varchar')" + "=" + "Peter"
then constructs a Select statement with the result as WHERE clause.
it does not build it like this, unescaped, unfiltered for injection etc, but this is the basic idea.
i can influence how the input is Transalted, meaning I can implement the methods:
lookupExpressionForField(String field)
lookUpOperatorMapping(String operator)
Formatvalues(List<String> values) | Formatvalues(String value)
constructClause(String expression,String operator,String value)
however i choose to do, i can change the parameter types, I can freely implement them. The less the better of course. So simply constructing a comma-seperated list with xPath would be optimal (like if i could somewhere just tick "enable /function()-syntax in xPath" in sqlserver and the /concat(if...) would work)
How about something like this:
SET NOCOUNT ON;
DECLARE #Books TABLE (ID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY, BookInfo XML);
INSERT INTO #Books (BookInfo)
VALUES (N'<book>
<title>a nice Novel</title>
<author>Maria</author>
<author>Peter</author>
</book>');
INSERT INTO #Books (BookInfo)
VALUES (N'<book>
<title>another one</title>
<author>Bob</author>
</book>');
SELECT *
FROM #Books bk
WHERE bk.BookInfo.exist('/book/author[text() = "Peter"]') = 1;
This returns only the first "book" entry. From there you can extract any portion of the XML field using the "value" function.
The "exist" function returns a boolean / BIT. This will scan through all "author" nodes within "book", so there is no need to concat into a comma-separated list only for use in an IN list, which wouldn't work anyway ;-).
For more info on the "value" and "exist" functions, as well as the other functions for use with XML data, please see:
xml Data Type Methods

Building dynamic query for Sql Server 2008 when table name contains " ' "

I need to fetch Table's TOP_PK, IDENT_CURRENT, IDENT_INCR, IDENT_SEED for which i am building dynamic query as below:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{1}]') AS CURRENT_IDENT, IDENT_INCR('[{1}]') AS IDENT_ICREMENT, IDENT_SEED('[{1}]') AS IDENT_SEED", pPrimaryKey, pTableName)
Here pPrimaryKey is name of Table's primary key column and pTableName is name of Table.
Now, i am facing problem when Table_Name contains " ' " character.(For Ex. KIN'1)
When i am using above logic and building query it would be as below:
SELECT (SELECT TOP 1 [ID] FROM [KIL'1]) AS TOP_PK, IDENT_CURRENT('[KIL'1]') AS CURRENT_IDENT, IDENT_INCR('[KIL'1]') AS IDENT_ICREMENT, IDENT_SEED('[KIL'1]') AS IDENT_SEED
Here, by executing above query i am getting error as below:
Incorrect syntax near '1'.
Unclosed quotation mark after the character string ') AS IDENT_SEED'.
So, can anyone please show me the best way to solve this problem?
Escape a single quote by doubling it: KIL'1 becomes KIL''1.
If a string already has adjacent single quotes, two becomes four, or four becomes eight... it can get a little hard to read, but it works :)
Using string methods from .NET, your statement could be:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{2}]') AS CURRENT_IDENT, IDENT_INCR('[{2}]') AS IDENT_ICREMENT, IDENT_SEED('[{2}]') AS IDENT_SEED", pPrimaryKey, pTableName, pTableName.Replace("'","''"))
EDIT:
Note that the string replace is now only on a new, third substitution string. (I've taken out the string replace for pPrimaryKey, and for the first occurrence of pTableName.) So now, single quotes are only doubled, when they will be within other single quotes.
You need to replace every single quote into two single quotes http://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx

Resources