I have a table that contains a GEOMETRY data type. SQL Server 2008 ships with a built in function to convert these GEOMETRY data types to GML - GEOMETRY.AsGml(). I believe this function is nothing more than a custom user defined function.
This function works exactly as expected, until I try to use it in a view that is joined to other tables/views. In that case, I get an error message along the lines "Remote function reference 'dbo.PROPERTY.SHAPE.AsGml' is not allowed, and the column name 'dbo' could not be found or is ambiguous."
What I have been doing is creating an initial view that contains all of the joins needed to get the desired fields, leaving the GEOMETRY field in its native format. Then, in a secondary view, I will perform the GML conversion.
The layering of these views has obvious performance implications, and I am wondering why I can't just do the AsGml() in the views with joins?
Using an inline Select statement solved this for me.
This didn't work:
SELECT dbo.H1N1_2009.COUNTY, dbo.states.STATE_NAME, dbo.states.geom.AsGml()
AS GML
FROM dbo.H1N1_2009 INNER JOIN dbo.states ON dbo.H1N1_2009.ID = dbo.states.ID
This works:
SELECT dbo.H1N1_2009.COUNTY, states_1.STATE_NAME,
(SELECT geom.AsGml() AS Expr1 FROM dbo.states WHERE(ID =dbo.H1N1_2009.ID)) AS GML
FROM dbo.H1N1_2009 INNER JOIN dbo.states AS states_1 ON dbo.H1N1_2009.ID states_1.ID
Hope this helps someone else.
Related
Our database solution is very JSON heavy, and as such, our SQL queries are all JSON based (for the most part). This includes extensive use of JSON_ARRAYAGG().
The problem I'm encountering is using a returned array of indexes in WHERE IN, which simply doesn't work. From what I can tell it's a simple formatting issue where MySQL wants an () encapsulation and a JSON array is a [] encapsulation.
For example:
SELECT COUNT(si.ID) AS item_count, JSON_ARRAYAGG(si.ID) AS item_array
FROM sourcing_item si;
Returns:
7, [1,2,3,4,5,6,7]
What I need to do is write a complex nested query that allows for selecting record IDs that are IN the JSON_ARRAYAGG result. Like:
SELECT si.item_name
FROM sourcing_item si
WHERE si.ID IN item_array
Of course the above doesn't work because MySQL doesn't recognize [] vs. ().
Is there a viable workaround for this issue? I'm surprised they haven't updated MySQL to allow the WHERE IN clause to work with a JSON array...
The MEMBER OF operator does this.
SELECT si.item_name
FROM sourcing_item si
WHERE si.ID MEMBER OF (item_array)
Using a SQLAlchemy class, I'm trying to generate a query that resembles
SELECT
DISTINCT(non_unique_key)
FROM
`tablename`,
UNNEST(tasks_dns) AS dns
WHERE
create_date_utc = TIMESTAMP("2020-12-31T23:59:59")
AND dns LIKE "%whatever%"
Being an implicit join using unnest(), I don't have a clue how to construct my statement.
Using a combination of .label() and moving the unnest() call around, I've managed to move the unnest clause to either the SELECT or WHERE clauses, but not in the FROM.
For example,
session.query(Table.non_unique_key).filter(func.unnest(Table.dns) != '').filter(Table.create_date == "2021-04-22")
leaves me with
SELECT `tablename`.`non_unique_key` AS `tablename_non_unique_key`
FROM `tablename`
WHERE unnest(`tablename`.`tasks_dns`) IS NOT NULL AND `tablename`.`create_date_utc` = %(create_date_utc_1)s
So far, using join() has just caused exceptions around not having a column to join on (which while yes, I understand what that means, I'm not sure how to get around that since an unnest is basically doing an expansion of a nested data type that doesn't have a column to join on.. which is probably where my ignorance around how to properly use SQLAlchemys join() method comes in)
Is this just a SQLAlchemy / BigQuery dialect issue at this point? Or am I just a dunce? I know the dialect library is still infant, but even with Postgres, I would have thought that this should be a somewhat common query pattern?
After some additional digging, I've figured it out
Model().query().select_from(func.unnest(Model.col1).alias("whatever")).filter()....
I have several procedures with same name but in different schemas. When these procedures raise an error, it is possible in parent procedure (which is calling these nested stored procedures) get schema of the procedure which raised an error ? For example i can get name from ERROR_PROCEDURE() but is there some option to get also SCHEMA ? Because otherwise i am not sure which exactly procedure throwed an error if there are many with same name.
I guess this feature is still missing
https://connect.microsoft.com/SQLServer/feedback/details/124627/schema-not-reported-in-the-error-procedure-function
but is there some workaround for this ?
Sadly, there is no 100% Workaround for this limitation in SQL-Server.
Shame on the MSSQL Dev Team for not rectifying this, well over a Decade later.
It should be as simple as adding a New Function like ERROR_ProcedureSchema() or ERROR_PROCID().
Here is a revived Post Requesting this Feature from way back in May of 2005:
https://feedback.azure.com/forums/908035-sql-server/suggestions/32894584-schema-not-reported-in-the-error-procedure-functio
I prefer to Log as much detail as possible about Exceptions I capture in my custom Error Handling Logic.
This is the best I could come up with to find the Schema Name:
DECLARE #Error_ProcSchemaName nVarChar(128)--Leave as Null if found in more than 1 Schema.
--Only Populate the #Error_ProcSchemaName if it Belongs to 1 Schema. - 04/08/2019 - MCR.
SELECT #Error_ProcSchemaName = S.name
FROM sys.objects as O
JOIN sys.schemas as S
ON S.schema_id = O.schema_id
JOIN
(
SELECT O.name[ObjectName], COUNT(*)[Occurrences]
FROM sys.objects as O
GROUP BY O.name
) AS Total
ON Total.ObjectName = O.name
WHERE O.name = ERROR_PROCEDURE()
AND Total.Occurrences = 1
Avoid using anything like OBJECT_SCHEMA_NAME(OBJECT_ID(ERROR_PROCEDURE())) as the string you pass into OBJECT_ID() should already have the Schema in it (which ERROR_PROCEDURE() does not).
Otherwise it will default to your Default Schema, which (in most cases) is dbo.
Run this Query to View all your Object Names that are Reused across Schemas:
--View Object Names that Exist in Multiple Schemas: - 04/08/2019 - MCR.
SELECT S.name[SchemaName], O.name[ObjectName], Total.Occurrences,
O.type[Type], O.type_desc[TypeDesc],
O.object_id[ObjectID], O.principal_id[PrincipalID], O.parent_object_id[ParentID],
O.is_ms_shipped[MS], O.create_date[Created], O.modify_date[Modified]
FROM sys.objects as O
JOIN sys.schemas as S
ON S.schema_id = O.schema_id
JOIN
(
SELECT O.name[ObjectName], COUNT(*)[Occurrences]
FROM sys.objects as O
GROUP BY O.name
) AS Total
ON Total.ObjectName = O.name
WHERE Total.Occurrences > 1
ORDER BY [ObjectName], [SchemaName]
If you only have a few Objects (Sprocs and Triggers) that overlap, then you might be okay not knowing the Schema as it may be obvious where it originated from.
However, if this is not the case, then you may need to either:
Change the Name of the Sproc/Trigger to make it Unique.
This option goes against the very fiber of my being.
If you are using Advanced Error Handling, then manually add the Schema of your Sproc/Trigger with OBJECT_SCHEMA_NAME(##PROCID)
in your Catch-Block when logging the Error.
Note: These options may not be possible due to the use of 3rd Party Sprocs you are not allowed to edit.
When Troubleshooting with multiple Sprocs/Triggers that share the same Name, you might be able to write a Custom Wrapper-Sproc to call your 3rd Party Sproc, then Log any exception thrown in your Wrapper to know exactly which Schema/Sproc caused it.
The Code Smell:
If you have multiple Sprocs/Triggers with the same name spread across various Schemas
then I would call that a "Code Smell".
Meaning, your Architecture is flawed.
You may not be properly encapsulating your logic for reuse.
There will be times when a name overlaps Schemas, but this should be rare and by coincidence only.
Misappropriating Schemas for Handling Multi-Tenant / UserGroup Access:
If you are trying something Multi-Tenant (storing data from different Organizations/UserGroups in the same Database and preventing them from seeing eachother's info) and running almost the same logic in each Schema that shares the Object Name, then that's a Design Problem.
You should have your data in Different Databases if Users will be accessing it directly
or have a TenantID or UserGroupID you always pass in and filter on everywhere when Users will be accessing from a Custom Application.
Some possible solutions I can think of:
Renaming each Stored Procedure so that they have different names in the different schemas.
Adding some debugging output to the Stored Procedures so that when they are being executed, you can see which one was in progress when your error occurred.
Running the SQL Profiler to see what is being called at the time your error occurs.
However, these are coming more from the perspective of trying to troubleshoot an issue you're having right now, rather than building in some error handling for potential future troubleshooting. You could always get these Stored Procedures to write some log files to disk somewhere so you can interrogate those logs when an error is experienced perhaps.
Is there any way to directly access the stemmer used in the FORMSOF() option of a CONTAINS Full Text Search query so that it returns the stems/inflections of an input word, not just those derivations that exist in a search column.
For example, the query
SELECT * FROM dbo.MyDB WHERE contains(CHAR_COL,'FORMSOF(INFLECTIONAL, prettier)')
returns the stem "pretty" and other inflections such as "prettiest" if they exists in the CHAR_COL column. What I want is to call the FORMSOF() function directly without referencing a column at all. Any chance?
EDIT:
The query that met my needs ended up being
SELECT * FROM
(SELECT ROW_NUMBER() OVER (PARTITION BY group_ID ORDER BY GROUP_ID) ord, display_term
from sys.dm_fts_parser('FORMSOF( FREETEXT, running) and FORMSOF(FREETEXT, jumping)', 1033, null, 1)) a
WHERE ord=1
Requires membership in the sysadmin
fixed server role and access rights to
the specified stoplist.
No. You can not do this. You can't get an access to stemmer directly.
You can get an idea of how it works by looking into Solr source code. But it might (and I guess will) be different from the one implemented in MS SQL FT.
UPDATE: It turns out that in SQL Server 2008 R2 you can do something quite close to what you want. A special table-valued UDF was added:
sys.dm_fts_parser('query_string', lcid, stoplist_id, accent_sensitivity)
it allows you to get a tokenization result (i.e. the result after applying word breaking, thesaurus and stop list application). So in case you feed it 'FORMSOF(....)' it will give you the result you want (well, you will have to process result set anyway). Here's corresponding article in MSDN.
The following doesn't work, but something like this is what I'm looking for.
select *
from Products
where Description like (#SearchedDescription + %)
SSRS uses the # operator in-front of a parameter to simulate an 'in', and I'm not finding a way to match up a string to a list of strings.
There are a few options on how to use a LIKE operator with a parameter.
OPTION 1
If you add the % to the parameter value, then you can customize how the LIKE filter will be processed. For instance, your query could be:
SELECT name
FROM master.dbo.sysobjects
WHERE name LIKE #ReportParameter1
For the data set to use the LIKE statement properly, then you could use a parameter value like sysa%. When I tested a sample report in SSRS 2008 using this code, I returned the following four tables:
sysallocunits
sysaudacts
sysasymkeys
sysaltfiles
OPTION 2
Another way to do this that doesn't require the user to add any '%' symbol is to generate a variable that has the code and exceute the variable.
DECLARE #DynamicSQL NVARCHAR(MAX)
SET #DynamicSQL =
'SELECT name, id, xtype
FROM dbo.sysobjects
WHERE name LIKE ''' + #ReportParameter1 + '%''
'
EXEC (#DynamicSQL)
This will give you finer controller over how the LIKE statement will be used. If you don't want users to inject any additional operators, then you can always add code to strip out non alpha-numeric characters before merging it into the final query.
OPTION 3
You can create a stored procedure that controls this functionality. I generally prefer to use stored procedures as data sources for SSRS and never allow dynamically generated SQL, but that's just a preference of mine. This helps with discoverability when performing dependency analysis checks and also allows you to ensure optimal query performance.
OPTION 4
Create a .NET code assembly that helps dynamically generate the SQL code. I think this is overkill and a poor choice at best, but it could work conceivably.
Have you tried to do:
select * from Products where Description like (#SearchedDescription + '%')
(Putting single quotes around the % sign?)
Dano, which version of SSRS are you using? If it's RS2000, the multi-parameter list is
not officially supported, but there is a workaround....
put like this:
select *
from tsStudent
where studentName like #SName+'%'
I know this is super old, but this came up in my search to solve the same problem, and I wound up using a solution not described here. I'm adding a new potential solution to help whomever else might follow.
As written, this solution only works in SQL Server 2016 and later, but can be adapted for older versions by writing a custom string_split UDF, and by using a subquery instead of a CTE.
First, map your #SearchedDescription into your Dataset as a single string using JOIN:
=JOIN(#SearchedDedscription, ",")
Then use STRING_SPLIT to map your "A,B,C,D" kind of string into a tabular structure.
;with
SearchTerms as (
select distinct
Value
from
string_split(#SearchedDescription, ',')
)
select distinct
*
from
Products
inner join SearchTerms on
Products.Description like SearchTerms.Value + '%'
If someone adds the same search term multiple times, this would duplicate rows in the result set. Similarly, a single product could match multiple search terms. I've added distinct to both the SearchTerms CTE and the main query to try to suppress this inappropriate row duplication.
If your query is more complex (including results from other joins) then this could become an increasingly big problem. Just be aware of it, it's the main drawback of this method.