How do I fix the SQLState_42000? - sql-server

I'm following a YouTube tutorial on implementing a database into a TwinCAT project, but when I check the connection, I get this error:
I'm pretty certain I don't have any syntax errors since my SQL table executed fine and my MAIN PRG is empty, so that leaves an access violation. The problem is I have no idea why I'm getting that error since I followed every step up to that point.
Is there anything I'm missing or I did wrong?
Just in case, here is my code I used to generate the SQL table:
use TestDB;
create table TwinCATSQL (bundleID varchar(10), profileLength decimal, profileWidth decimal, profileHeight decimal, profileFlex decimal, pieces int,
bundleSizeX int, bundleSizeY int, bundleLevel int, destination int, manualRepackOnly bit);
select * from TwinCATSQL;

In my case, i struggled with the same problem and couldn't actually solve it yet, but i just used the "master" database to run tests with SQL, since it seems to be a problem with the user authentication. With the master database you just uncheck the Authentication Box and it shoul let you check the database with no problems.

Related

Find functions using temp tables where NVARCHAR limit does not match its referenced table definition

Problem: Junior SQL dev here, working with a SQL Server database where we have many functions that use temp tables to pull data from various tables to populate Crystal reports etc. We had an issue where a user action in our client caused a string to overflow the defined NVARCHAR(100) character limit of the column. As a quick fix, one of our seniors decided on a schema change to set the column definition to NVARCHAR(255), instead of fixing the issue of the the string getting too long. Now, we have lots of these table based functions that are using temp tables referencing the column in question but the temp table variable is defined as 100 instead of 255.
Question: Is there an easy way to find and update all of these functions? Some functions might not reference the table/column in question at all, but some heavily rely on this data to feed reports etc. I know I can right click a table and select "View Dependencies" in SQL Server Management Studio, but this seems very tedious to have to go through all of them and then update our master schema before deploying it to all customers.
I thought about a find and replace if there is a way to script or export the functions but I fear a problem I will run into is one variable in one function might be declared as TransItemDescription NVARCHAR(100) and one might be TransItemDesc NVARCHAR (100). I've heard of people avoiding temp tables maybe because of these issues so maybe there is just bad database design here?
Thus far I've been going through them one at a time using "View Dependencies" in SSMS.
I think the best solution would be to script out the whole database into a single script from SSMS. Then use Notepad++ (or equivalent) to either find:
All occurrences of NVARCHAR(100)
All occurrences of the variable name, e.g. TransItemDescription, TransItemDesc.
Once you have found all occurrences then make a list of all of the functions to be fixed. Then you would still need to do a manual fix to all functions, but once complete the issue should be totally resolved.

Can sql server give me a warning if I try and insert unicode without the N prefix

ok, so the support team have once again updated a value in the database and forgot the N prefix so replaced it with ???s.
Is there something that can be done on either the database (sqlserver 2012) or sqlserver management studio 2012 that can stop or warn people?
And why does the database automagically change the update to ?s, if it's a nvarchar column and I'm passing in Unicode without N why not have it error?
This is not an issue with the driver being used to connect to SQL Server. It is simply an implicit conversion happening due to using the wrong datatype in the string literal. Everything has a type. A number 2 by itself is, by default, an INT, and not a DECIMAL or FLOAT or anything else. A number 2.0 is, by default, a NUMERIC (same as DECIMAL), and not a FLOAT, etc. Strings are no different. A string expressed as 'something' is 8-bit ASCII, using the Code Page of the database that the query is running in. If you had used '随机字符中国' in a database set to one of the collations that supports those characters in an 8-bit encoding (it would be a Double-Byte Character Set (DBCS)) then it would not have translated to ? since it would have had the character in its Code Page.
CREATE DATABASE [ChineseSimplifiedPinyin] COLLATE Chinese_Simplified_Pinyin_100_CI_AS;
Then, run this:
USE [ChineseSimplifiedPinyin];
SELECT '随机字符中国';
and it will return those characters and not ??????.
And why does the database automagically change the update to ?s, if it's a nvarchar column and I'm passing in Unicode without N why not have it error?
The UPDATE is not being changed. An implicit conversion is happening because you are using the wrong datatype for string literals when not prefixing with the N. This is no different than doing the following:
DECLARE #Test INT;
SET #Test = 2.123;
SELECT #Test;
which returns simply a 2.
Now, it might be possible to set up a Policy to trap implicit conversions, but that would be too far reaching and would likely break lots of stuff. Even if you could narrow it down to implicit conversions going from VARCHAR to NVARCHAR that would still break code that would otherwise work in the current situation: inserting 'bob' into an NVARCHAR field would be an implicit conversion yet there would be no data loss. And you can't trap any of this in a Trigger because that is after-the-fact of receiving the implicitly converted data.
The best way to ensure nobody forgets to insert or update without the N prefix is to create a web app or console app that would be an interface for this (which is probably a good idea anyway since that will also prevent someone from using the wrong WHERE clause or forgetting to use one altogether, both of which do happen). Creating a small .NET web or console app is pretty easy and .NET strings are all Unicode (UTF-16 Little Endian). Then the app takes the data and submits the INSERT or UPDATE statement. Be sure to use a parameter and not dynamic SQL.
Given that the ? character is valid in this field, if it can be determined that multiple ?s would never naturally occur, then you can probably prevent this issue on cases involving more than a single character getting converted by creating an INSERT, UPDATE Trigger that cancels the operation if multiple ?s in a row are present. Using a Trigger as opposed to a Check Constraint allows for a little more control, especially over the error message:
CREATE TRIGGER tr_PreventLosingUnicodeCharacters
ON SchemaName.TableName
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF (EXISTS (SELECT *
FROM INSERTED ins
WHERE ins.column1 LIKE N'%??%')
)
BEGIN
ROLLBACK; -- cancel the INSERT or UPDATE operation
DECLARE #Message NVARCHAR(1000);
SET #Message =
N'INSERT or UPDATE of [column1] without "N" prefix results in data loss. '
+ NCHAR(13) + NCHAR(10)
+ N'Please try again using N''string'' instead of just ''string''.';
RAISERROR(#Message, 16, 1);
RETURN;
END;
END;
And if 2 ?s can naturally happen, then do the search for ??? and then it is only 1 or 2 character items that might slip by. In either case, this should catch enough erroneous entries so that you only need to fix things on rare occasions (hopefully :).
Is there something that can be done on either the database (sqlserver 2012) or sqlserver management studio 2012 that can stop or warn people?
Not to my knowledge. About the only thing I can think of would be:
ALTER TABLE some_table ADD CONSTRAINT stop_messing_it_up CHECK (NOT column1 LIKE '%?%');
but you can't tell the difference between a question mark that came from prior content-mangling and a real question mark, so that would only be workable if it were also invalid to put a question mark in the database.
why does the database automagically change the update to ?s, if it's a nvarchar column
It doesn't matter what the column is, it's the type of the string literal in the query expression. In SQL Server (only), non-NATIONAL string literals can only contain characters in the locale-specific (“ANSI”) code page, so the data loss occurs before the content gets anywhere near your table:
SELECT '随机字符中国';
??????
SELECT N'随机字符中国';
随机字符中国

Access 2000 - invalid character value for cast specification (#0) - Access to SQL

Lately I have migrated my Access 2000 backend data and tables to a 2012 SQL server. In the access frontend I have linked the SQL tables that were migrated. Most of it is working fine except for (now) one form.
In this form the data is being loaded from the SQL server using this query:
SELECT * FROM qryAbonementens WHERE EindDatum is null or EindDatum>=now()
It also used a filter and sort:
((Lookup_cmbOrderNummer.Omschrijving="GJK"))
And the sort:
Lookup_cmbOrderNummer.Omschrijving
These things may be irrelevant but Ill just post as much as possible.
The data loads in the form perfectly, however when I try to change a record in the form, I keep getting the:
error invalid character value for cast specification (#0)
While checking out posts with the same problem I encountered this post:
MS Access error "ODBC--call failed. Invalid character value for cast specification (#0)"
This made me believe that I was missing a PK somewhere so First I checked the linked table in Access design mode:
Tekst = text, Numeriek = numeric, Datum/tijd = date (sorry for it being dutch).
The same table in SQL looked like this:
They both have PK so I guess this is not the problem.
Though, when looking at both datatypes you can see 2 differences on the InkoopPrijs and VerkoopPrijs fields. In SQL these two are decimals(30,2) and in the design view in the linked access table they are, I guess unknown, and so they are being cast to text values. Perhaps this is the cause of my error message?
The record I am trying to change and which gives the error is this one (but it is on all the records):
I've read somewhere that adding a timestamp field to the SQL server could help but I have no clue it also works in my case or how to do this.
As you have guessed, the decimal(30, 2) columns are the problem.
They are too large for Access to be used as numbers.
I can reproduce the problem with Access 2010, although I can enter numeric data into the field. But when I enter text, I get the exact same error message.
decimal(18,2) works fine (it's the default decimal precision for Sql Server 2008).
Surely you don't have prices in the 10^30 range? :-)
You might also consider using the money datatype instead, although I don't know how well Access 2000 works with that.
Alright I got it fixed. #Andre451 post about changing the 30,2 decimal values in the SQL server to 18,2 gave me the the record is changed by another user error. This caused me to look differently at the problem and instead of fixing the
error invalid character value for cast specification (#0)
error I looked at the
record was changed by another user error
I came across this post: Linked Access DB "record has been changed by another user"
Here someone suggested to add a TimeStamp field to the SQL table. So I did and now it seems to work again! And it also seems to work with the original (decimal 30,2) value!

Create custom error message in check constraints in SQL SERVER 2008

I'd like to see the ability to attach custom error messages to CONSTRAINT objects, specifically CHECK constrints. Either directly or via a custom error number in sysmessages.
I've seen developers have to create triggers. I think that's not a good reason to implementing it.
I'm using SQL SERVER 2008.
You could name your constraint with a user message.
For Example:
ADD CONSTRAINT
[Foo cannot be greater than Bar. Please be sure to check your foos and bars next time.]
CHECK (foo <= Bar)
I know this is an old post, but I've found something that may make it a bit easier to provide clearer error messages for check constraints to the end-user: the names of check constraints can include carriage returns and line feeds, so the error message can be made a bit easier to see.
E.g. creating the following constraint produces the error message below. (the blank lines between the [ and ] are intentional i.e. they are part of the constraint name.)
ALTER TABLE dbo.Sales WITH CHECK ADD CONSTRAINT [
ERROR:
You have stupidly entered a negative selling price. Please report to detention.
] CHECK ([SellingPrice] >= 0.00)
GO
And when this constraint fails, the resulting message is:
I tried putting markup in the error message (i.e. constraint name), like <b>message</b> and *message*, but to no avail. And it may be possible, but really unwieldy, to use this for foreign key constraints as well. I haven't tried it.
So it's not a 100% solution, but hopefully easier for the user to see the intended error message.
Edit (2022-02-09): Since database object names are stored using the sysname data type (search for 'sysname' on this page), they cannot be longer than 128 characters. Use short error messages 😄
You can't directly
A CHECK constraint fails with a standard error message. You could use a TRY/CATCH block to parse the error and throw your own (RAISERROR) or use a trigger.
I'd check first so it doesn't fire, either is SQL or in client code. And of course you leave the constraint there to protect data integrity
So if you have a constraint
ALTER TABLE MyTable WITH CHECK
ADD CONSTRAINT CK_MyTable_foobar CHECK (#foo <= #Bar)
You run the following SQL code or equivalent in your client code:
...
IF #foo > #bar
RAISERROR ('foo (%i) can not be greater than bar (%i)', 16, 1, #foo, #bar)
INSERT MyTable (foo, bar) VALUES (#foo, #bar)
....

SQLServer cannot find my user defined function function in stored procedure

I must have some permissions wrong, but I can't figure out how. The following code is simplified but I can't even get this to work
CREATE FUNCTION ufTest
(
#myParm int
)
RETURNS int
AS
BEGIN
DECLARE #Result int
SELECT #Result = #myParm + 1
RETURN #Result
END
GO
Then I just want to be able to call the function from a stored procedure:
CREATE PROCEDURE dbo.[uspGetGroupProfileService]
#id int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #otherId int;
SET #otherId = dbo.ufTest(#id);
END
SQLServer keeps telling me that it can't find dbo.ufTest. It shows up under [DB]\Programmability\Functions\Scalar-valued Functions but I can't figure out how to use it.
Anybody have any idea what I'm doing wrong?
EDIT
As indicated by the selected answer below, you can't always trust the SSMS Intellisense. One thing that you can try, other than just trying to execute the script, is forcing an Intellisense refresh with CTRL + SHIFT + R
https://blog.sqlauthority.com/2013/07/04/sql-server-how-to-refresh-ssms-intellisense-cache-to-update-schema-changes/
Works for me.
Try CREATE FUNCTION dbo.ufTest ...
I assume your default schema can't be dbo and it's ending up in a different schema. Otherwise the only explanation I can think of is you might need to grant permissions on it.
Script out the UDF and check the schema name. It's probably not dbo. I would change the UDF definition to specifically include dbo. In other words:
CREATE FUNCTION dbo.ufTest
Had the exact same problem and mine got fixed by simply restarting SQL Server Management Studio.
Just posting this in case anyone else did everything right and is still not able to call his function.
I just had an issue where this was the error and all of the advice on this column was failing as well.
Be sure double check your function declaration type and usage of that type.
I declared a return-type table and tried to call it with Select functionName() where I needed to use SELECT * FROM functionName()
As a last resort if any of the above and especially #jrdev22's answer did not help you (and left you stumped why), restart the SQL Server service in Configuration Manager since restarting the SSMS alone sometimes does not reset everything (e.g. similar to when creating a new login instance but not being able to login with it).
SQL Server Configuration Manager> SQL Server Services > SQL Server > Restart
Try calling it with a select instead of a set. And you checked that out belongs to the dbo schema?
It appears it might be a bug in the query editor. The Function appears in the tree in the right place but even naming the function dbo.xxxxxx the function doesn't appear in the query editor until you close and open a new session, then it appears if you type in dbo.
If you change the name of the function the old non existing fuction is avalable but not the new name. Refresh doesn't fix this only closing the session and starting a new one.
Why I say this might be a bug is that the permissions properties for Table function includeds a blue link to the schema properties but the Scalar functions it doesn't. So it may be a deeper lying bug in the way the schema is set up in the first place for which there may be a work around. Or maybe the schema in the database I am working on has not been set up correctly.
Hopefully someone else can shine some light on this issue.
If you are unable to find the function that you have just created there are two reasons for it.
you are using the wrong function name you need to add dbo.function name to get it.
I've also found one more issue like even though correct name is entered and also it is existing in the object explorer after refreshing you are unable to find it when you are trying to use the function.
In this case simply close the sql server and reopen it and you should be able to see the function.

Resources