How to convert regexp_substr(Oracle) to SQL Server? - sql-server

I have a data table which has a column as Acctno what is expected shows in separate column
|Acctno | expected_output|
|ABC:BKS:1023049101 | 1023049101 |
|ABC:UWR:19048234582 | 19048234582 |
|ABC:UEW:1039481843 | 1039481843 |
I know in Oracle SQL which I used the below
select regexp_substr(acctno,'[^:]',1,3) as expected_output
from temp_mytable
but in Microsoft SQL Server I am getting an error that regexp_substr is not a built in function
How can I resolve this issue?

We can use PATINDEX with SUBSTRING here:
SELECT SUBSTRING(acctno, PATINDEX('%:[0-9]%', acctno) + 1, LEN(acctno)) AS expected_output
FROM temp_mytable;
Demo
Note that this answer assumes that the third component would always start with a digit, and that the first two components would not have any digits. If this were not true, then we would have to do more work.

Just another option if the desired value is the last portion of the string and there are not more than 4 segments.
Select *
,NewValue = parsename(replace(Acctno,':','.'),1)
from YourTable

Related

Spark dataframe changes column values when writing on SQL server

I'm facing a very specific problem. I'm working on a pyspark notebook on Databricks. I run the following command:
my_df.select("insert_date").distinct().show()
and get:
+--------------------+
| insert_date|
+--------------------+
|2021-12-22 09:52:...|
|2021-12-20 16:36:...|
+--------------------+
then, I run:
my_df.persist()
my_df.write.option("truncate", "true").mode("overwrite").jdbc(sqlDbUrl, "[dbo].[my_table]",properties = connectionProperties)
my_df.unpersist()
my_df.select("insert_date").distinct().show()
and get:
+--------------------+
| insert_date|
+--------------------+
|2021-12-22 09:52:...|
+--------------------+
if I interrogate the SQL database, the result is consistent with the second show:
select distinct insert_date from [dbo].[my_table]
**result**
insert_date
2021-12-22 09:52:31.000
and this is undesired, I would like to preserve the two distinct values for column insert_date within the SQL table, and I can't get why this is not happening.
Further information:
Databricks column type: string
python version: 3
SQL column type: NVARCHAR(MAX)
There are no costraints such as default value for the SQL column
For any further information, please ask in the comments.
Thanks in advance!

What is the SQL Server 2016 equivalent of using group_contact() and locate() functions?

A while ago, I asked "How can I generate a breadcrumb of Categories in pure MySQL?", which a fellow stackoverflow member provided this neat code for my MySQL needs:
select group_concat(t2.name order by locate(concat('/', t2.id, '/'), concat(t1.path, '/')) separator ' - ') breadcrumb
from mdl_course_categories t1,
mdl_course_categories t2
where locate(concat('/', t2.id, '/'), concat(t1.path, '/'))
Today, I find I need an SQL Server 2016 solution to this combination of functions (group_concat() and locate()) to replicate this functionality. I tried running this code against this database, but I am hit with this error message instead:
SQLState: 42000
Error Code: 156
Message: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near the keyword 'order'.
I checked other questions, but was unable to transfer this knowledge to my needs. How can I replicate this functionality in SQL Server 2016?
Edit: I've read the links that #Bacon Bits provided (thank you!), but doing this in SQL Server 2016 seems as possible as programming a slice of cheese to fly to the moon. Unfortunately upgrading is not an option, so I'm stuck with this hot mess. All I need to do is replace the numbers in the path column with the name as per the id. E.g.
| id | name | path | should display as |
|---------|---------------|-------------------|--------------------------------|
| 1 | Fruit and Veg | /1 | Fruit and Veg - Fruit |
| 436547 | Fruit | /1/436547 | Fruit and Veg - Fruit |
| 4657598 | Apples | /1/436547/4657598 | Fruit and Veg - Fruit - Apples |
SO FRUSTRATING! Here's my code so far:
select
stuff((',' + t2.name), 1, 1, charindex(concat('/', t2.id, '/'), concat(t1.path, '/')))
from prefix_course_categories t1,
prefix_course_categories t2
where charindex(concat('/', t2.id, '/'), concat(t1.path, '/'))
This produces the following error:
SQLState: 42000
Error Code: 4145
Message: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]An expression of non-boolean type specified in a context where a condition is expected, near 'ORDER'.
Help appreciated, thank you.
GROUP_CONCAT() doesn't have a good equivalent in MS SQL Server until SQL Server 2017, when the STRING_AGG() function is introduced. SQL Server 2016 and earlier can fake it with the STUFF FOR XML PATH method, which is arcane, obnoxious, irritating, and has pitfalls where you can have XML entities in the output if you don't call it just right. But it does generally perform fairly well.
MySQL's LOCATE() is roughly equivalent to CHARINDEX(), I think. There's also the PATINDEX() function, which is a bit more flexible but doesn't perform as well.

SSRS System.InvalidCastException - at OracleDataReader.GetDecimal(Int32 i)

I have an SSRS report that was pointed to SQL Server views, which pointed to Oracle tables. I edited the SSRS report Dataset so as to query directly from the Oracle db. It seems like a very simple change until I got this error message:
System.InvalidCastException: Specified cast is not valid.
With the following details...
Field ‘UOM_QTY’ and it also says at
Oracle.ManagedDataAccess.Client.OracleDataReader.GetDecimal(Int32 i).
The SELECT statement on that field is pretty simple:
, (DELV_RECEIPT.INV_LBS/ITEM_UOM_XREF.CONV_TO_LBS) AS UOM_QTY
Does anyone know what would cause the message, and how to resolve the error? My objective is use to use the ORACLE datasource instead of SQL SERVER.
Error 1
Severity Code Description Project File Line Suppression State
Warning [rsErrorReadingDataSetField] The dataset ‘dsIngredientCosts’ contains a definition for the Field ‘UOM_QTY’. The data extension returned an error during reading the field. System.InvalidCastException: Specified cast is not valid.
at Oracle.ManagedDataAccess.Client.OracleDataReader.GetDecimal(Int32 i)
at Oracle.ManagedDataAccess.Client.OracleDataReader.GetValue(Int32 i)
at Microsoft.ReportingServices.DataExtensions.DataReaderWrapper.GetValue(Int32 fieldIndex)
at Microsoft.ReportingServices.DataExtensions.MappingDataReader.GetFieldValue(Int32 aliasIndex) C:\Users\bl0040\Documents\Visual Studio 2015\Projects\SSRS\Project_ssrs2016\Subscription Reports\Feed Ingredient Weekly Price Avg.rdl 0
Error 2
Severity Code Description Project File Line Suppression State
Warning [rsMissingFieldInDataSet] The dataset ‘dsIngredientCosts’ contains a definition for the Field ‘UOM_QTY’. This field is missing from the returned result set from the data source. C:\Users\bl0040\Documents\Visual Studio 2015\Projects\SSRS\Project_ssrs2016\Subscription Reports\Feed Ingredient Weekly Price Avg.rdl 0
Source Tables:
+------------+---------------+-------------+---------------+-----------+
| Source | TABLE_NAME | COLUMN_NAME | DataSize | COLUMN_ID |
+------------+---------------+-------------+---------------+-----------+
| ORACLE | DELV_RECEIPT | INV_LBS | NUMBER (7,0) | 66 |
+------------+---------------+-------------+---------------+-----------+
| ORACLE | ITEM_UOM_XREF | CONV_TO_LBS | NUMBER (9,4) | 3 |
+------------+---------------+-------------+---------------+-----------+
| SQL SERVER | DELV_RECEIPT | INV_LBS | numeric (7,0) | 66 |
+------------+---------------+-------------+---------------+-----------+
| SQL SERVER | ITEM_UOM_XREF | CONV_TO_LBS | numeric (9,4) | 3 |
+------------+---------------+-------------+---------------+-----------+
The error went away after adding a datatype conversion statement to the data selection.
, CAST(DELV_RECEIPT.INV_LBS/ITEM_UOM_XREF.CONV_TO_LBS AS NUMERIC(9,4)) AS UOM_QTY
Can anyone provide some information on why the original query would be a problem and why the CAST would fix these errors? I tried casting the results because someone on Code Project forum said...
why don't you use typed datasets? you get such head aches just because
of not coding in a type-safe manner. you have a dataset designer in
the IDE which makes the life better, safer, easier and you don't use
it. I really can't understand.
Here is an approach to fix this error with an extension method instead of modifying the SQL-Query.
public static Decimal MyGetDecimal(this OracleDataReader reader, int i)
{
try
{
return reader.GetDecimal(i);
}
catch (System.InvalidCastException)
{
Oracle.ManagedDataAccess.Types.OracleDecimal hlp = reader.GetOracleDecimal(i);
Oracle.ManagedDataAccess.Types.OracleDecimal hlp2 = Oracle.ManagedDataAccess.Types.OracleDecimal.SetPrecision(hlp, 27);
return hlp2.Value;
}
}
Thank you for this but what happens if your query looks like:
SELECT x.* from x
and .GetDecimal appears nowhere?
Any suggestions in that case? I have created a function in ORACLE itself that rounds all values in a result set to avoid this for basic select statements but this seems wrong for loading updateable datasets...
Obviously this is an old-school approach to getting data.

execute stored procedure with dbslim with Fitnesse (Selenium,Xebium)

https://github.com/markfink/dbslim
I'd like to execute the stored procedures with DbSlim using Fitnesse (Selenium, Xebium)
now what I tried to do is:
!define dbQuerySelectCustomerbalance (
execute dbo.uspLogError
)
| script | Db Slim Select Query | !-${dbQuerySelectCustomerbalance}-! |
which gives a green indicator,
however Microsoft SQL Server profiler gives no actions/logging...
so what i'd like to know is: is it possible to use dbslim for executing stored procedures,
if yes
what is the correct way to do it?
By the way, the connection to the Database i've on 1 page, and on the query page i included the connection to the database. (is that ok?)
Take out the !- ... -!. It is used to escape wikified words. But in this case you want it to be translated to the actual query.
!define dbQuerySelectCustomerbalance ( execute dbo.uspLogError )
| script | Db Slim Select Query | ${dbQuerySelectCustomerbalance} |
| show | data by column index | 1 | and row index | 1 |
You can add in the last line which outputing the first column of the first row for testing purpose if your SP is returning some result (or you can create one simple SP just to test this out)
Specifying the connection anywhere before this block will be fine, be it on the same page or in an SetUp/SuiteSetUp/normal page included/executed before.

SQL Server built-in function name

I'm trying to update sum columns data like this:
update
tableName
set
score = myFunction(tableName.id)
In other hands I want to have a table like this:
column1 | column2
------------------------------
id1 | myFunction(id1)
id2 | myFunction(id2)
id3 | myFunction(id3)
id4 | myFunction(id4)
I defined myFunction as a scalar-valued functions. I also tried it as a table-valued function
but I see this error in SQL Server 2012:
Msg 195, Level 15, State 10, Line 14
'myFunction' is not a recognized built-in function name.
Please help me
Try using the full name of the function, including the database and schema name:
update
tableName
set
score = <database>.<schema>.myFunction(tableName.id)
I think only the schema name is needed, but I've gotten in the habit of putting both.
The documentation explains that at least the two part name is needed. If you don't know what schema are, then the following will probably work:
update
tableName
set
score = dbo.myFunction(tableName.id)

Resources