VS Crashes when using T-SQL OPENJSON and SELECT * - json

When using the below code the VS 2019 crashed without fail. Though it was originally working, possibly prior to a recent update (or upgrade to VS 2019 from VS 2017)
The error message implied a too long identifier and related to a specific file. I temp resolved this by accessing my project via Team Explorer as opposed to startup window. It resurfaced as soon as I edited the file. So I went line-by-line to find the culprit, the code below is the culprit. I cannot understand why it causes the crash.
DECLARE #Characteristics nvarchar(4000) = (SELECT * FROM OPENJSON(#Details)
WITH ([Firstname] nvarchar(256) N'$.firstname',[Lastname] nvarchar(256) N'$.lastname') FOR JSON PATH, WITHOUT_ARRAY_WRAPPER);
It's a legitimate command and SQL accepts including deployments. For my purposes and because I control the WITH clause, "SELECT *", is an acceptable deviation from my practice of stating the columns in the SELECT clause.
VS no longer crashes now that I declare each expected column in the SELECT clause. If somebody has an alternative resolution to solving this problem I would appreciate it.

You do not show enough - at least for me - to understand your issue completely...
What I get:
You want to use SELECT *
You are controlling the WITH clause (I assume: You build it dynamically in your application)
You did not show the actual error message (please do this the next time), but I get, that the error depends on the difference of
SELECT * FROM ...
SELECT Firstname, Lastname FROM ...
I cannot reproduce your issue, but I guess, that there are more sources involved in your actual statement and that * might include more than you tell us.
Did you try to use a table alias after the WITH?
DECLARE #Details NVARCHAR(MAX)=N'[{"a":"a1", "b":"b1"},{"a":"a2","b":"b2"}]';
SELECT
(
SELECT tbl.* --<-- Using "tbl.*" instead of "*"
FROM OPENJSON(#Details)
WITH(a NVARCHAR(100)
,b NVARCHAR(100)) tbl --<-- table alias "tbl"
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
);

Related

" ( " not valid in this position, expecting an identifier in MySQL

Today is, 1/30/2022, I have been following along with an #AlexTheAnalyst video. I am on a Mac and using MySQL version 8.0.27. (The video is using windows based SQL Server Workbench) I am stuck! I am trying to creating a temporary table function. MySQL is not liking the # in the table name #PercentPopVaccinated as used in the video. When I remove it and run the function/query without the # I get 0 rows returned. I have researched on stackoverflow etc. and I am not coming up with a solution that I understand. (Newbie here)
I have dropped the table that was created and I am starting over.
I am getting an error when creating the temp table that states MySQL is expecting an identifier after the first " ( ". Anyone else have a similar issue?
Create Table #PercentPopulationVaccinated
(
continent nvarchar(255),
location nvarchar(255),
date datetime,
population numeric,
new_vaccinations numeric,
RollingVacCount numeric
)
Insert into #PercentPopulationVaccinated
Select dea.continent, dea.location, dea.date, dea.population, vac.new_vaccinations
, SUM(cast(vac.new_vaccinations as UNSIGNED)) OVER (Partition by dea.location Order by dea.location, dea.date)
as RollingVacCount
-- (RollingVacCount/population)*100
From project_portfolio.covid_deaths dea
Join project_portfolio.covid_vaccinations vac
On dea.location = vac.location
and dea.date = vac.date
where dea.continent is not null
-- order by 2,3
Select *, (RollingVacCount/Population)*100
From #PercentPopulationVaccinated;
So I'd say the underlying problem is that you are watching a video tutorial that is using SQL Server, but you are using MySQL. There are many similarities, but it is not going to be an exact match. For instance, the # sign creates a temporary table in Sql Server, but the # is not valid in MySQL. If you want to use a different database service than the tutorial you are watching is for, you are going to have to translate some concepts for yourself.
Another commenter already posted this link, which indicates the syntax for creating temp tables in MySQL.
https://dev.mysql.com/doc/refman/8.0/en/create-table.html#create-table-temporary-tables

Common Table Expressions -- Using a Variable in the Predicate

I've written a common table expression to return hierarchical information and it seems to work without issue if I hard code a value into the WHERE statement. If I use a variable (even if the variable contains the same information as the hard coded value), I get the error The maximum recursion 100 has been exhausted before statement completion.
This is easier shown with a simple example (note, I haven't included the actual code for the CTE just to keep things clearer. If you think it's useful, I can certainly add it).
This Works
WITH Blder
AS
(-- CODE IS HERE )
SELECT
*
FROM Blder as b
WHERE b.PartNo = 'ABCDE';
This throws the Max Recursion Error
DECLARE #part CHAR(25);
SET #part = 'ABCDE'
WITH Blder
AS
(-- CODE IS HERE )
SELECT
*
FROM Blder as b
WHERE b.PartNo = #part;
Am I missing something silly? Or does the SQL engine handle hardcoded values and parameter values differently in this type of scenario?
Kindly put semicolon at the end of your variable assignment statement
SET #part ='ABCDE';
Your SELECT statement is written incorrectly: the SQL Server Query Optimizer is able to optimize away the potential cycle if fed the literal string, but not when it's fed a variable, which uses the plan that developed from the statistics.
SQL Server 2016 improved on the Query Optimizer, so if you could migrate your DB to SQL Server 2016 or newer, either with the DB compatibility level set to 130 or higher (for SQL Server 2016 and up), or have it kept at 100 (for SQL Server 2008) but with OPTION (USE HINT ('ENABLE_QUERY_OPTIMIZER_HOTFIXES')) added to the bottom of your SELECT statement, you should get the desired result without the max recursion error.
If you are stuck on SQL Server 2008, you could also add OPTION (RECOMPILE) to the bottom of your SELECT statement to create an ad hoc query plan that would be similar to the one that worked correctly.

How to find out the changes happened for all objects

How I can find out the changes happened in database like modifying functions, table indexes, procedures and adding or removing columns.
Here in this query
select * from sys.objects
where type IS NOT NULL
and modify_date between '2013-07-21' and '2013-07-29'
but here I am getting created objects list and modifying list, but if I deleted any object it is not showing anything.
How can I get the all the changes happened in database between specific dates?
Try a source control solution for SQL. I've used RedGate's SQL Source Control before, and it records a history of changes like this, including who made the change, and what was changed.
http://www.red-gate.com/products/sql-development/sql-source-control/
It's a bit expensive, but it's good. I don't know if there's a way to do it (especially deletions) just with SQL itself.
Many of these incidents are recorded in the default trace.
DECLARE #path NVARCHAR(260);
SELECT
#path = REVERSE(SUBSTRING(REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT
LoginName,
HostName,
StartTime,
ObjectName,
TextData -- may or may not be populated
FROM sys.fn_trace_gettable(#path, DEFAULT)
WHERE EventClass IN
(
164, -- object:altered
46, -- object:created
47 -- object:deleted
)
AND StartTime >= '20130721' AND StartTime < '20130730';
Why you should never use BETWEEN for date range queries.

Use SQL Server FTS Stemmer

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.

MySQL developer here -- Nesting with select * finicky in Oracle 10g?

I'm writing a simple diagnostic query then attempting to execute it in the Oracle 10g SQL Scratchpad. EDIT: It will not be used in code. I'm nesting a simple "Select *" and it's giving me errors.
In the SQL Scratchpad for Oracle 10g Enterprise Manager Console, this statement runs fine.
SELECT * FROM v$session sess, v$sql sql WHERE sql.sql_id(+) = sess.sql_id and sql.sql_text <> ' '
If I try to wrap that up in Select * from () tb2 I get an error, "ORA-00918: Column Ambiguously Defined". I didn't think that could ever happen with this kind of statement so I am a bit confused.
select * from
(SELECT * FROM v$session sess, v$sql sql WHERE sql.sql_id(+) = sess.sql_id and sql.sql_text <> ' ')
tb2
You should always be able to select * from the result set of another select * statement using this structure as far as I'm aware... right?
Is Oracle/10g/the scratchpad trying to force me to accept a certain syntactic structure to prevent excessive nesting? Is this a bug in scratchpad or something about how oracle works?
When Oracle parses a SELECT *, it expands it out to an actual list of the columns to be selected. Since your inline view contains two columns named SQL_ID, this results in an ambiguous reference.
Interestingly, using ANSI join syntax seems to cause it to alias the duplicate column names automatically, and therefore avoids the error.
select * from
(select * from v$session sess left outer join v$sql sql on sql.sql_id=sess.sql_id and sql.sql_text <> ' ')
Incidentally, it's not clear to me why you chose that condition on sql_text. I don't expect that column would ever contain a single space. Are you really trying to filter out NULLs? If so, why use an outer join at all?
One of the general rules of thumbs at my place of employment is that SELECT * is never allowed. Explicitly define what columns you need; not only is it more readable, but less likely to have issues down the road