I'm using Simple.Data.Ado.Schema.Column to get the schema for the columns in my SQL Server database. But from browsing around the classes and going into the source code, it seems Simple.Data does not query for the IS_NULLABLE value.
Is there any way to retrieve from Simple.Data if a column is nullable or not? If not then I will probably need to modify the source code to include that info as well.
No, Simple.Data doesn't have any functionality that requires the nullable information, so it's not there.
Related
Is it possible to provide a default value or a query to provide a value to an unmapped column in the target table using Redgate SQL Data Compare?
To explain the scenario I have a configuration database that holds settings data for several database instances. The data is all in the same shape, but the config database has an additional InstanceID field in most tables. This allows me to filter my compare to only compare against the InstanceID relating to the source Instance database. However if I generate Insert scripts they fail because the Target Instance ID fields are non nullable. I want to provide a default value that is then used in the Insert Scripts. Is this doable?
SQL Data Compare doesn't have an easy way of doing this I'm afraid.
There is one way to do it - you could create a view that selects everything from the source table along with a computed column, which just provides the "default value" that you want to insert. Then you can map the view to the table in the target database and compare them, deploying from the result.
I hope this helps.
I found a query like select cast (:v as customtabletype) from dual.
Not able to understand what is the meaning of above line, written as dynamic query.
:<variablename>, in your case ":v", is what is known as a bind variable.
Essentially, this is a placeholder which is replaced with another value as the SQL statement is executed.
For more in-depth reading it is probably worth looking for bind variables in the Oracle documentation, as there is a lot of information available on why they're used and their benefits.
I get the following error:
Cannot use empty object or column names. Use a single space if necessary.
Msg 1038, Level 15, State 3, Line 1
and the query command looks like:
SELECT TOP 100 PERCENT
[].[cms_page].[pa_id], [].[cms_page].[pa_key],
[].[cms_page].[pa_title], [].[cms_page].[pa_keywords],
[].[cms_page].[pa_description], [].[cms_page].[pa_header],
[].[cms_page].[pa_created], [].[cms_page].[pa_modified],
[].[cms_page].[pa_language] FROM [cms_page]
WHERE
[cms_page].[pa_key] = #pa_key0
ORDER BY
[pa_id] ASC;
Strange indeed. Why does this happen? I'm using SubSonic 2.1.
Connectionstring:
<add name="OCDB" connectionString="Network Library=DBMSSOCN;Data Source=127.0.0.1,1433;Initial Catalog=test_db;User ID=test;Password=testpwd"/>
Edit: Well the solution was just to simply generate and rebuild the Data Access Layer and I was good to go.
You seem to be using a 3 part name with part of it empty, i.e. '[].'
It looks as though the query text is being constructed with an empty table schema.
Those empty [] square brackets should contain something like "dbo" to make the query syntactically valid. I don't know enough about SubSonic to give you a code sample though.
I'm not familiar with SubSonic, but have you tried a simpler query to test if you have your syntax correct? Does this query even work in SQL Server (Management Studio / Query Analyzer)?
Just looking at this from the perspective of SQL Server, you are using way too many brackets. If I was writing that query in SQL Server, it would look more like what I wrote below. I'm not sure about the variable #pa_key0, is this query part of a stored procedure or does SunSonic replace this variable when the query is ran?
SELECT
pa_id,
pa_key,
pa_title,
pa_keywords,
pa_description,
pa_header,
pa_created,
pa_modified,
pa_language
FROM
cms_page
WHERE
pa_key = #pa_key0
ORDER BY
pa_id ASC;
I think you need to set the schema for Subsonic to use. This thread seems to have some information:
Subsonic - How to use SQL Schema / Owner name as part of the namespace?
I have a table which links to another table in the ASP.NET membership schema.
Problem is, all the PKs for the ASP.NET tables are uniqueidentifier so mine has to be too. When I add a SqlDatasource and call its Insert() method, I get the following error:
Cannot insert the value NULL into column 'DiscountCode', table 'CreamDb.dbo.CustomInfo1'; column does not allow nulls. INSERT fails.
The statement has been terminated.
The uniqueidentifier is also treated as an object (its data type), but there is no Guid data type. I had this problem before, but the schema was much simpler so I could fix it.
How can I go about fixing this? If I get rid of the data type part in the markup (so just leave the field/parameter name but not the data type stuff), I get another error so that is not possible.
Thanks
What do you mean by "there is no Guid data type"? What's wrong with System.Guid? Can't you just use Guid.NewGuid(), set the field appropriately, and do the insert?
EDIT: Just to give a bit more meat: attach an event handler to the Inserting event, and populate the field then, via the DbCommand returned by SqlDataSourceCommandEventArgs.Command. Or change the SQL used by the INSERT command to ask the database to populate the GUID field for you.
A popullar approach when dealing with references to the ASP.NET Membership Provider's data is, instead of keeping a proper foreign key to the GUIDs, instead store something like the LoweredUserName in your table. Then, use the Membership Provider's API to interact with the object you need. In some cases, you need an ObjectDataSource abstraction layer to accomplish CRUD scenarios.
Set the default value of the column in SQL Sever to "newid()".
Asp.net won't send the value, and the field will get a new guid.
I will explain problem with an example:
There is two table in my database, named entry, tags
There is a column named ID_ENTRY in both table. When I add a record to table, entry, I have to take the ID_ENTRY of last added record and add it to table, tags. How can I do it?
The only way to do this is with multiple statements. Using dynamic sql you can do this by separating each statement in your query string with a semi-colon:
"DECLARE #ID int;INSERT INTO [Entry] (...) VALUES ...; SELECT #ID = scope_identity();INSERT INTO [TAGS] (ID_ENTRY) VALUES (#ID);"
Make sure you put this in a transaction to protect against concurrency problems and keep it all atomic. You could also break that up into two separate queries to return the new ID value in the middle if you want; just make sure both queries are in the same transaction.
Also: you are using parameterized queries with your dynamic sql, right? If you're not, I'll personally come over there and smack you 10,000 times with a wet noodle until you repent of your insecure ways.
Immediatly after executing the insert statement on first table, you should query ##IDENTITY doing "SELECT ##identity". That will retrieve the last autogenerated ID... and then just insert it on the second table.
If you are using triggers or something that inserts rows... this may be not work. Use Scope_Identity() instead of ##IDENTITY
I would probably do this with an INSERT trigger on the named entry table, if you have all of the data you need to push to the tags table available. If not, then you might want to consider using a stored procedure that creates both inside a transaction.
If you want to do it in code, you'll need to be more specific about how you are managing your data. Are you using DataAdapter, DataTables, LINQ, NHibernate, ...? Essentially, you need to wrap both inserts inside a transaction of some sort so that either inserts get executed or neither do, but the means to doing that depend on what technology you are using to interact with the database.
If you use dynamic sql, why not use Linq to Entity Framework, now EF is the recommend data access technology from Microsoft (see this post Clarifying the message on L2S Futures from ADO.NET team blog), and if you do an insert with EF the last identity id will available for you automatically, I use it all the time it's easy.
Hope this helps!
Ray.