Showing posts with label procedures. Show all posts
Showing posts with label procedures. Show all posts

Monday, March 19, 2012

ControlParameter and Stored Procedures

I'm sure I'm missing something silly. I have 3 textboxes, a stored procedure and a gridview. The user will put something in the 3 boxes, click submit, and see a grid with stuff (I hope). However, the grid will only return data is I EXCLUDE the controlparameters and only use the sessionparameter. It's like the stored proc won't even fire!

HTML:

<formid="form1"runat="server">
<div>
Lastname: <asp:textboxid="Lastname"runat="server"></asp:textbox>
Hobbies: <asp:textboxid="Hobbies"runat="server"></asp:textbox><br/>
Profession: <asp:textboxid="Profession"runat="server"></asp:textbox>
<asp:buttonid="Button1"runat="server"text="Button"/><br/>
<asp:gridviewskinid="DataGrid"id="GridView1"runat="server"allowpaging="True"allowsorting="True"autogeneratecolumns="False"datasourceid="SqlDataSource1">
<columns>
<asp:boundfielddatafield="Username"headertext="Username"sortexpression="Username"/>
<asp:boundfielddatafield="Lastname"headertext="Lastname"sortexpression="Lastname"/>
<asp:boundfielddatafield="Firstname"headertext="Firstname"sortexpression="Firstname"/>
</columns>
</asp:gridview><asp:sqldatasourceid="SqlDataSource1"runat="server"connectionstring="<%$ ConnectionStrings:HOAConnectionString %>"
selectcommand="spAddressBookSelect"selectcommandtype="StoredProcedure">
<selectparameters>
<asp:sessionparameterdefaultvalue="0"name="CommunityID"sessionfield="CommunityID"type="Int32"/>
<asp:controlparametercontrolid="Lastname"name="Lastname"propertyname="Text"type="String"/>
<asp:controlparametercontrolid="Profession"name="Profession"propertyname="Text"type="String"/>
<asp:controlparametercontrolid="Hobbies"name="Hobbies"propertyname="Text"type="String"/>
</selectparameters>
</asp:sqldatasource></div></form>

sp signature:
ALTER PROCEDURE[dbo].[spAddressBookSelect]
@.CommunityIDint= 0,
@.Lastnamevarchar(200) =NULL,
@.Professionvarchar(200) =NULL,
@.Hobbiesvarchar(200) =NULL

I'm guessing that you mean it doesn't work when all three textboxes aren't filled in. It should work if you fill out all of them. If that is the case, then your problem is that you are passing a NULL value if the textbox is blank, and you haven't set the "CancelSelectOnNullParameter" property of the sqldatasource control to false, so yes, it's not firing the SELECT.

|||Nicely done! That was it, thanks!

controlling security through stored procedures -- 2005 behaviour

Hi!

I'm trying to control security through sps -- meaning execute permissions are granted on stored procedures, and no users have read/write permissions on tables, etc directly.

Which works fine as long as all objects referenced are in the same db as the procedure.

An issue arises when a stored procedure accesses a table in another database:

Getting a : Msg 229 SELECT permission denied on object 'blah' Even though the procedure is created by sysadmin.

Has this changed since 2000? I'm pretty sure in 2000 it would've worked as the sp would be executed in sp owner's security context.

Moreover, when I try to use EXECUTE AS in the sp as a workaround, I am getting the following, no matter what account I try to impersonate:

Msg 916, Level 14, State 1, Procedure vvv, Line 4
The server principal % is not able to access the database "blah" under the current security context.

any ideas?
Thanks!

Most likely this scenario worked on Windows 2000 with cross-database ownership chaining enabled. Turning on this feature is not recommended, as it may lead to an elevation of privileges (i.e. the DB administrators of the source database may escalate their privileges to become DB administrators on the target DB).

The reason why your stored procedure marked with “execute as” is not working is because the impersonated context is (by default) scoped only to the surrent (source) database, and stripped down from it's server-scoped permissions and privileges. If you wish to use this impersonated context outside the source DB, you need to establish a trust relationship on the target DB.

To solve this problem, you can probably use digital signatures to solve your problem; by signing the stored procedure with a certificate you have a way to ensure that the code has not been tampered with. If at run time the signature matches the code, the certificate can be used in two ways:

* As a secondary identity for the execution context. This means that if there is a user mapped to the signing certificate, the permissions on that user will be used to calculate the permissions on the object.

* When the module (SP) is marked with execute as, the signature will work as an authenticator, that means the signature will be used to vouch for the impersonated context in the stored procedure

Note that for the secondary identity approach, the signature will be added to the current context therefore, if the current context is not a valid one on the server scope (i.e. the caller is an approle), the certificate as secondary identity cannot be used on cross database scenario.

The second approach on the other hand establishes a whole new context on top of the calling context, and it is the signature the one vouching for this new context on the target database.

I am posting a small demo at the end taht I hope will help you.

Thanks a lot for your comments and feedback.

-Raul Garcia
SDE/T
SQL Server Engine
This posting is provided "AS IS" with no warranties, and confers no rights.

-

/*******************************************************************

*

* This posting is provided "AS IS" with no warranties, and
* confers no rights.

*

* Author: Raulga

* Date: 08/24/2005

* Description:

* This demo shows how to use digital signatures to access
* resources on a different database by using digitaly signed stored
* procedures to control the access rather than using cross database
* ownership chaining.

*

* The first SP will be using the siganture as a secondary identity
* on top of the calling context. This means that only a context with
* a server-presence will succeed on this call (i.e. approles will not
* be able to accsss the resources on the target database as they

* don't have a server presence).

*

* The second approach will be by specifying a context switch
* (EXECUTE AS) on the stored procedure and using the signature as an
* authenticator; this means that the signature can vouch for the
* impersonated context (specifid on the module). This mechanism will
* allow to access the resources regardless of the original calling
* context because a new context (vouched by the signature) is placed
* on top of the orginal one, but requires more managment.

*

* (c) 2005 Microsoft Corporation. All rights reserved.

*

***********************************************************************************************/

CREATE DATABASE db_Source

go

CREATE DATABASE db_Target

go

CREATE LOGIN dbo_db_Source WITH PASSWORD = 'My S0uRc3 D8 p@.55W0rD!'

CREATE LOGIN dbo_db_Target WITH PASSWORD = 'My +@.r637 D8 p@.55W0rD!'

go

-- Change the ownership for the source and the target databases

ALTER AUTHORIZATION ON DATABASE::db_Source to dbo_db_Source

ALTER AUTHORIZATION ON DATABASE::db_Target to dbo_db_Target

go

-- This principal will be the data owner, he can access the data on

-- the target database, and he controls the stored procedures on the

-- source database

CREATE LOGIN data_owner WITH PASSWORD = 'd@.+4 0wn3R'

-- This principal should only have access to the data via the stored

-- procedures

CREATE LOGIN someuser WITH PASSWORD = 's0m3 p@.55w0Rd'

go

use db_Target

go

CREATE USER someuser

CREATE USER data_owner WITH DEFAULT_SCHEMA = data_owner

go

CREATE SCHEMA data_owner AUTHORIZATION data_owner

go

CREATE TABLE data_owner.MyTable( data nvarchar(100) )

go

INSERT INTO data_owner.MyTable values ( N'My data' )

go

use db_Source

go

CREATE USER someuser

CREATE USER data_owner WITH DEFAULT_SCHEMA = data_owner

go

CREATE SCHEMA data_owner AUTHORIZATION data_owner

go

-- ALlow someuser to execute any module on the schema called data_owner

GRANT EXECUTE ON SCHEMA::data_owner TO someuser

go

-- Create a stored procedure that uses the default execution context

-- (the caller's context) at runtime

CREATE PROC data_owner.sp_GetMyData01

AS

select * from db_Target.data_owner.MyTable

go

-- Create a stored procedure similar to teh previous one, but this time we will explicitly

-- use the data_owner context via EXECUTE AS

CREATE PROC data_owner.sp_GetMyData02

WITH EXECUTE AS 'data_owner'

AS

select * from db_Target.data_owner.MyTable

go

-

-- Let's see what is the behavior without any signatures

--

-- You can either start new connections or just use the

-- EXECUTE AS LOGIN & REVERT statements I show here for testing

-- Execute as the data owner

-

EXECUTE AS LOGIN = 'data_owner'

go

-- will succeed

EXEC data_owner.sp_GetMyData01

go

-- Will fail as the impersonated context is not trusted on the target
-- database

EXEC data_owner.sp_GetMyData02

go

REVERT

go

-

-- Execute as someuser

-

EXECUTE AS LOGIN = 'someuser'

go

-- will fail due to the lack of permissions on the target database

EXEC data_owner.sp_GetMyData01

-- will fail as the impersonated context is not trusted on the target
-- database

EXEC data_owner.sp_GetMyData02

go

REVERT

go

-

-- Signing the stored procedures

--

-- Create 2 certificates one to sign each SP.

-- Note that I am using passwords to protect the private keys.

-- It is also possible to use a DB master key to protect private the
-- keys, please refer to BOL for more information on the key
-- hierarchy

CREATE CERTIFICATE cert_GetMyData01

ENCRYPTION BY PASSWORD = 'GetMyData01 c3r+ p@.55w0Rd'

WITH SUBJECT = 'Certificate to sign sp_GetMyData01'

go

CREATE CERTIFICATE cert_GetMyData02

ENCRYPTION BY PASSWORD = 'GetMyData02 c3r+ P455W0Rd'

WITH SUBJECT = 'Certificate to sign sp_GetMyData02'

go

-- Now sign the stored procedures, as the cert's

-- private keys are protected by passwords, we have to use the
-- passwords to sign

ADD SIGNATURE TO data_owner.sp_GetMyData01 BY CERTIFICATE cert_GetMyData01

WITH PASSWORD = 'GetMyData01 c3r+ p@.55w0Rd'

go

ADD SIGNATURE TO data_owner.sp_GetMyData02 BY CERTIFICATE cert_GetMyData02

WITH PASSWORD = 'GetMyData02 c3r+ P455W0Rd'

go

-- Let's take a quick look to the metadata for the signed modules

SELECT schema_name( c.schema_id ) as schema_name, c.name,

b.name, a.crypt_property as 'module siganture' FROM

sys.crypt_properties a,

sys.certificates b,

sys.objects c

WHERE a.thumbprint = b.thumbprint AND a.class = 1
AND a.major_id = c.object_id

go

-- Depending on your application and environment, sometimes you may
-- not want to leave the private keys on the database, and either
-- destroy the private keys (this way, they can never be used to
-- sign anything else), or back up a copy of the private keys and
-- store them in a safe place. For this demo I will just destoy the
-- private keys as we don't need them anymore

ALTER CERTIFICATE cert_GetMyData01 REMOVE PRIVATE KEY

ALTER CERTIFICATE cert_GetMyData02 REMOVE PRIVATE KEY

go

-- Now, we need to create a backup for the certificate public data.

-- We will need to import it back on teh target database.

BACKUP CERTIFICATE cert_GetMyData01 TO FILE = 'cert_GetMyData01.cer'

BACKUP CERTIFICATE cert_GetMyData02 TO FILE = 'cert_GetMyData02.cer'

go

use db_Target

go

-- Import the certificates on the target database, note that we don't
-- need the private keys

CREATE CERTIFICATE cert_GetMyData01
FROM FILE = 'cert_GetMyData01.cer'

go


CREATE CERTIFICATE cert_GetMyData02
FROM FILE = 'cert_GetMyData02.cer'

go

-- Now let's create users mapped to each one of the certificates.

-- As permissions can only be granted to principals and not directly

-- to a certificate, we need to map the certificate to a user.

-- Note: The cert-mapped user SID is derived from teh certificate
-- thumbprint

-- therefore any 2+ principals (login or user in any database)
-- mapped to the

-- same certificate will have the same SID and will refer to the same

-- principal for practical purposes.

CREATE USER cert_GetMyData01 FOR CERTIFICATE cert_GetMyData01

go

CREATE USER cert_GetMyData02 FOR CERTIFICATE cert_GetMyData02

go

-- For the first SP, grant the permissions to the cert-mapped
-- user directly

GRANT SELECT ON data_owner.MyTable TO cert_GetMyData01

go

-- For the second SP, we want only AUTHENTICATE permissiion, this
-- will allow teh certificate to vouch for the context only on this
-- database.

-- Note: As the trust is only accross database and not accross the
-- instance, the new context is only valid for database operations,
-- and will not honor any server-scoped permissions.

GRANT AUTHENTICATE TO cert_GetMyData02

go

USE db_Source

go

-

-- Let's see what is the behavior without any signatures

--

-- You can either start new connections or just use the

-- EXECUTE AS LOGIN & REVERT statements I show here for testing

-- Execute as the data owner

-

EXECUTE AS LOGIN = 'data_owner'

go

-- will succeed

EXEC data_owner.sp_GetMyData01

go

-- will succeed as the module is executing as "data_owner"

-- (the module is specifying the context itself), and the

-- signature is vouching for this context

EXEC data_owner.sp_GetMyData02

go

REVERT

go

-

-- Execute as someuser

-

EXECUTE AS LOGIN = 'someuser'

go

-- will succed as the certificate will be granting the required
-- permission to select the data from the table

-- Note that someuser is a valid context accross the server at
-- this point

EXEC data_owner.sp_GetMyData01

-- will succeed as the module is executing as "data_owner"

-- (the module is specifying the context itself), and the

-- signature is vouching for this context

EXEC data_owner.sp_GetMyData02

go

REVERT

go

-

-- cleanup

USE master

go

DROP DATABASE db_Source

go

DROP DATABASE db_Target

go

DROP LOGIN dbo_db_Source

DROP LOGIN dbo_db_Target

DROP LOGIN data_owner

DROP LOGIN someuser

go

|||

Raul -- thanks a lot for taking the time to do this. Excellent explanation and demo!

Sunday, March 11, 2012

Controling Replation agent actions

Hello there
I some questions:
1. Iw'd like to run some store procedures before i'm starging the
replication every day. Dose it enouth to add the task before the replication
task?
2. If the replication faild i would like to make sure that none of the
changes will be made.
3. IF an error occur can i nevegat it to the type of error:
if the error is data error(validation of foreign key) or connection error.
So i can give it order to run 5 minutes afterword?
4. Can i output the errors to outside files in order that other programs
that use sql server (Access) can give a message to the user?
Roy,
adding another step would be fine, or another job which runs sp_start_job
after your code had finished.
Trapping errors is really well catered fro in SQL 2005 but not so easy in
SQL 2000. You'd be better testing your changes in code rather than
attempting your changes eg look for a PK value before trying the FK insert.
If the PK doesn't exist, then logging this to a table and taking appropriate
actions eg making your own error message available to Access.
Cheers,
Paul Ibison SQL Server MVP, www.replicationanswers.com
(recommended sql server 2000 replication book:
http://www.nwsu.com/0974973602p.html)
|||1) I would make these procs the first job step of your replication job
2) Double click on the job step, select advanced and have it run a job or
script on failure.
3) This is a little tricky - the error should be in the msrepl_errors table
in the distribution database where the agent is run. You can query it there,
but the error may not be there depending on the error message. What you
would need to do is restart the agent on failure, but this time use the
verbose agent profile. The complete error message will now be in the
msrepl_Errors table. Errors are also logged in text files and dumped in
%WindDir%\system32 and will have an err extension. You can poll for them
using FileSystemWatcher.
4) You might want to poll msrepl_errors as discussed above and write to an
access database. Or you could fire something using the Replication Alert
Agent Failure.
Hilary Cotter
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"Roy Goldhammer" <roy@.hotmail.com> wrote in message
news:ePub0LyAGHA.2656@.tk2msftngp13.phx.gbl...
> Hello there
> I some questions:
> 1. Iw'd like to run some store procedures before i'm starging the
> replication every day. Dose it enouth to add the task before the
> replication
> task?
> 2. If the replication faild i would like to make sure that none of the
> changes will be made.
> 3. IF an error occur can i nevegat it to the type of error:
> if the error is data error(validation of foreign key) or connection error.
> So i can give it order to run 5 minutes afterword?
> 4. Can i output the errors to outside files in order that other programs
> that use sql server (Access) can give a message to the user?
>
>
|||Whell Hilary
I've made an error in the replication and no MSRepl_Errors table were
created
After i got the error when i run the agent on the enterprise manager i
opened the query anlyser with the distribution database and i counldn't see
the table
When will the table appear?
"Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
news:OYG7KczAGHA.272@.TK2MSFTNGP09.phx.gbl...
> 1) I would make these procs the first job step of your replication job
> 2) Double click on the job step, select advanced and have it run a job or
> script on failure.
> 3) This is a little tricky - the error should be in the msrepl_errors
> table in the distribution database where the agent is run. You can query
> it there, but the error may not be there depending on the error message.
> What you would need to do is restart the agent on failure, but this time
> use the verbose agent profile. The complete error message will now be in
> the msrepl_Errors table. Errors are also logged in text files and dumped
> in %WindDir%\system32 and will have an err extension. You can poll for
> them using FileSystemWatcher.
> 4) You might want to poll msrepl_errors as discussed above and write to an
> access database. Or you could fire something using the Replication Alert
> Agent Failure.
> --
> Hilary Cotter
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
> Looking for a FAQ on Indexing Services/SQL FTS
> http://www.indexserverfaq.com
> "Roy Goldhammer" <roy@.hotmail.com> wrote in message
> news:ePub0LyAGHA.2656@.tk2msftngp13.phx.gbl...
>

Thursday, March 8, 2012

Control of flow around "CREATE PROCEDURE"

Hi there.
I am trying to write a single script to create some stored procedures. One
of the stored procedures however, refers to a database which may or may not
be present on the server. In the case of that database NOT being present, I
would like to create the stored procedure with different contents (as the
original contents cause script errors when the missing database os referred
to). However, I'm having trouble controlling the flow of execution in the
script around CREATE PROCEDURE as it needs to be the first instruction in a
batch.
Basically I'd like to do something like this:
Use SomeOtherDatabase
GO
IF( DB_ID('MyDatabaseName') is not NULL ) --if the database exists
CREATE PROCEDURE p_MyStoredProc
AS
SELECT * FROM MyDatabaseName.dbo.SomeTable
GO
ELSE --The database doesn't exist
CREATE PROCEDURE p_MyStoredProc
AS
PRINT 'The Database doesnt exist on this server'
GO
The reason I want to take this approach is to avoid script errors when the
script is run on servers where that database is missing.
Any ideas how I should go about this?
Any help would be much appreciated!!Len,
Kinda questionable approach. Try something like this using Dynamic SQL:
IF DB_ID('MyDatabaseName') IS NOT NULL
EXEC('CREATE PROCEDURE ...')
ELSE
EXEC('CREATE PROCEDURE ...')
Also see Erland's article:
http://www.sommarskog.se/dynamic_sql.html
HTH
Jerry
"len" <len@.discussions.microsoft.com> wrote in message
news:7F82FDC3-CE0F-427E-8BBB-50DD3798E4F8@.microsoft.com...
> Hi there.
> I am trying to write a single script to create some stored procedures. One
> of the stored procedures however, refers to a database which may or may
> not
> be present on the server. In the case of that database NOT being present,
> I
> would like to create the stored procedure with different contents (as the
> original contents cause script errors when the missing database os
> referred
> to). However, I'm having trouble controlling the flow of execution in the
> script around CREATE PROCEDURE as it needs to be the first instruction in
> a
> batch.
> Basically I'd like to do something like this:
> Use SomeOtherDatabase
> GO
> IF( DB_ID('MyDatabaseName') is not NULL ) --if the database exists
> CREATE PROCEDURE p_MyStoredProc
> AS
> SELECT * FROM MyDatabaseName.dbo.SomeTable
> GO
> ELSE --The database doesn't exist
> CREATE PROCEDURE p_MyStoredProc
> AS
> PRINT 'The Database doesnt exist on this server'
> GO
> The reason I want to take this approach is to avoid script errors when the
> script is run on servers where that database is missing.
> Any ideas how I should go about this?
> Any help would be much appreciated!!|||Why not just fix the code that is calling the wrong proc? Seems like an
unusual architecture if neither your client code or your procs will
know whether a database exists or not.
Where possible I find it better to reference other databases only in
views and then write procs against the views. That way views act as
your database indirection and the database names are hard-coded in as
few places as possible.
David Portas
SQL Server MVP
--|||Perfect - thanks! - I had tried dynamic SQL but got stuck on sp_executesql a
s
my stored proc was over 4000 chars long - Erland's article covers this thoug
h
"Jerry Spivey" wrote:

> Len,
> Kinda questionable approach. Try something like this using Dynamic SQL:
> IF DB_ID('MyDatabaseName') IS NOT NULL
> EXEC('CREATE PROCEDURE ...')
> ELSE
> EXEC('CREATE PROCEDURE ...')
> Also see Erland's article:
> http://www.sommarskog.se/dynamic_sql.html
> HTH
> Jerry
> "len" <len@.discussions.microsoft.com> wrote in message
> news:7F82FDC3-CE0F-427E-8BBB-50DD3798E4F8@.microsoft.com...
>
>|||I'm not too happy with the architecture myself! Unfortunately it's a legacy
thing whereby my principal aim was just to minimize the number of scripts
needed to install some additional stored procs.
"David Portas" wrote:

> Why not just fix the code that is calling the wrong proc? Seems like an
> unusual architecture if neither your client code or your procs will
> know whether a database exists or not.
> Where possible I find it better to reference other databases only in
> views and then write procs against the views. That way views act as
> your database indirection and the database names are hard-coded in as
> few places as possible.
> --
> David Portas
> SQL Server MVP
> --
>

Sunday, February 19, 2012

Consuming Web Services from the SQL CLR

Hi there,

I've been following Vineets and David's procedures to consume web

services using SQL CLR to the t. I created my web service in C#.NET

2005, and generated my proxy using this command:


wsdl /par:oldwsdlconfig.xml /o:ExactMobileService.cs /n:Project360.SmsService http://www.exactmobile.co.za/interactive/interactivewebservice.asmx

I added both files to the project, set Generate Serialization Assembly to on and compiled it.
I then generated a strong name key for the assembly and signed my assembly with that key.
Inside my post-build event I added the following script:


"E:\Development\Microsoft

Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /force

/compiler:/keyfile:SmsServiceKey.snk /t:StoredProcedures

$(TargetDir)$(TargetName).dll


This compiled into my assembly, the XmlSerializer assembly and then added strong name key to both.


In SQL Server 2005, I enabled CLR, made my DB trustworthy, created my

first assembly with permissions EXTERNAL ACCESS and then the

XmlSerializer assembly with permissions SAFE. I created my stored

procedure and ran it. When I did I got this error which I assumed the

XmlSerializer was supposed to solve for me:

System.InvalidOperationException:

Cannot load dynamically generated serialization assembly. In some

hosting environments assembly load functionality is restricted,

consider using pre-generated serializer. Please see inner exception for

more information. > System.IO.FileLoadException: LoadFrom(),

LoadFile(), Load(byte[]) and LoadModule() have been disabled by the

host.

I have seen alot of posts about this error, but none of them has been able to solve my problem.

Please can you help me?

O'Connor

Hi O'Connor,

As you have experienced, there are a few cases where sgen does not solve the problem of dynamically loading the XmlSerializer assembly.There is usually always a possible workaround, but it can vary depending on exactly what your code is doing.I was intending on writing some more blog posts about solutions to these dynamic assembly loading problems, but haven't had the time to finish them yet.

The problem you're most likely hitting is that the code doing the XmlSerialization uses an XmlSerializer constructor that does not check for the pre-generated (sgened) assemblies.This could be either directly in your code, or in other .NET Framework code that does this, such as in a strongly typed ADO.NET Dataset.This is covered in the msdn documentation for XmlSerializer if you look at the "Dynamically Generated Assemblies" section http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

If this is indeed the problem, then the easiest way to fix this is to modify your code to instead use one of the constructors that does check for a pre-generated XmlSerializer assembly.This might be more difficult if it is not your code that is directly calling the XmlSerializer constructor.If you can include the full callstack of the error message you shared below and a snippet of the code where the XmlSerialization is happening, I should be able to help you fix it.

Steven

|||Hi Steven,

Thanks for getting back to me in such a short time.
I was playing with it last night and finally got it working.
My types aren't complex, I only use strings within my assembly (as it is a sms service)
What I did eventually do to fix it was to remove the post build script and set the "Generate Serialization Assembly" on the build tab of the project properties to ON.
It seems that using the sgen tool, the serialization assembly wasn't generated exactly the way that the CLR required it.

I found this website to be very useful in the end:
http://www.u2u.be/Article.aspx?ART=WebServicesinSQL05

Regards,
O'Connor

|||

Hello Steven,

I am currently facing exactly the same strange problem as the initiator of this thread. I want to call a simple webservice from a stored procedure in SQL 2005. I've already tried the different ways of getting the serializer assemblies (using sgen and the build option in VS 2005). I also registered both assemblies one after another in in my SQL 2005 database. The db is trustworthy, assemblies are both marked with "external_access".

But I keep getting the Dynamic Load exception. In your previous post you said you could help if you have the full callstack; here it is...

Msg 6522, Level 16, State 1, Procedure CreateNotification, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'CreateNotification':
System.InvalidOperationException: Cannot load dynamically generated serialization assembly. In some hosting environments assembly load functionality is restricted, consider using pre-generated serializer. Please see inner exception for more information. > System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.

System.IO.FileLoadException:
at System.Reflection.Assembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection)
at System.Reflection.Assembly.Load(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence securityEvidence)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources)
at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources)
at System.CodeDom.Compiler.Code
...
System.InvalidOperationException:
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, CompilerParameters parameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, compilerParameters parameters, Assembly assembly, Hashtable assemblies)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.FromMappings(XmlMapping[] mappings, Type type)
at System.Web.Services.Protocols.SoapClientType..ctor(Type type)
at System.Web.Services.Protocols.SoapHttpClientProtocol..ctor()
at MAN.Applications.HFIF.Database.ClrExtensions.WebServiceSoapClient..ctor(String ...

How can I change the behaviour of my soap client class to use a particular XmlSerializer constructor that checks for pre-generated assemblies? Could you please give me a hint?

Thanks very much for your help. Frank

Consuming Web Services from the SQL CLR

Hi there,

I've been following Vineets and David's procedures to consume web

services using SQL CLR to the t. I created my web service in C#.NET

2005, and generated my proxy using this command:


wsdl /par:oldwsdlconfig.xml /o:ExactMobileService.cs /n:Project360.SmsService http://www.exactmobile.co.za/interactive/interactivewebservice.asmx

I added both files to the project, set Generate Serialization Assembly to on and compiled it.
I then generated a strong name key for the assembly and signed my assembly with that key.
Inside my post-build event I added the following script:


"E:\Development\Microsoft

Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /force

/compiler:/keyfile:SmsServiceKey.snk /t:StoredProcedures

$(TargetDir)$(TargetName).dll


This compiled into my assembly, the XmlSerializer assembly and then added strong name key to both.


In SQL Server 2005, I enabled CLR, made my DB trustworthy, created my

first assembly with permissions EXTERNAL ACCESS and then the

XmlSerializer assembly with permissions SAFE. I created my stored

procedure and ran it. When I did I got this error which I assumed the

XmlSerializer was supposed to solve for me:

System.InvalidOperationException:

Cannot load dynamically generated serialization assembly. In some

hosting environments assembly load functionality is restricted,

consider using pre-generated serializer. Please see inner exception for

more information. > System.IO.FileLoadException: LoadFrom(),

LoadFile(), Load(byte[]) and LoadModule() have been disabled by the

host.

I have seen alot of posts about this error, but none of them has been able to solve my problem.

Please can you help me?

O'Connor

Hi O'Connor,

As you have experienced, there are a few cases where sgen does not solve the problem of dynamically loading the XmlSerializer assembly.There is usually always a possible workaround, but it can vary depending on exactly what your code is doing.I was intending on writing some more blog posts about solutions to these dynamic assembly loading problems, but haven't had the time to finish them yet.

The problem you're most likely hitting is that the code doing the XmlSerialization uses an XmlSerializer constructor that does not check for the pre-generated (sgened) assemblies.This could be either directly in your code, or in other .NET Framework code that does this, such as in a strongly typed ADO.NET Dataset.This is covered in the msdn documentation for XmlSerializer if you look at the "Dynamically Generated Assemblies" section http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

If this is indeed the problem, then the easiest way to fix this is to modify your code to instead use one of the constructors that does check for a pre-generated XmlSerializer assembly.This might be more difficult if it is not your code that is directly calling the XmlSerializer constructor.If you can include the full callstack of the error message you shared below and a snippet of the code where the XmlSerialization is happening, I should be able to help you fix it.

Steven

|||Hi Steven,

Thanks for getting back to me in such a short time.
I was playing with it last night and finally got it working.
My types aren't complex, I only use strings within my assembly (as it is a sms service)
What I did eventually do to fix it was to remove the post build script and set the "Generate Serialization Assembly" on the build tab of the project properties to ON.
It seems that using the sgen tool, the serialization assembly wasn't generated exactly the way that the CLR required it.

I found this website to be very useful in the end:
http://www.u2u.be/Article.aspx?ART=WebServicesinSQL05

Regards,
O'Connor

|||

Hello Steven,

I am currently facing exactly the same strange problem as the initiator of this thread. I want to call a simple webservice from a stored procedure in SQL 2005. I've already tried the different ways of getting the serializer assemblies (using sgen and the build option in VS 2005). I also registered both assemblies one after another in in my SQL 2005 database. The db is trustworthy, assemblies are both marked with "external_access".

But I keep getting the Dynamic Load exception. In your previous post you said you could help if you have the full callstack; here it is...

Msg 6522, Level 16, State 1, Procedure CreateNotification, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'CreateNotification':
System.InvalidOperationException: Cannot load dynamically generated serialization assembly. In some hosting environments assembly load functionality is restricted, consider using pre-generated serializer. Please see inner exception for more information. > System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.

System.IO.FileLoadException:
at System.Reflection.Assembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection)
at System.Reflection.Assembly.Load(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence securityEvidence)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources)
at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources)
at System.CodeDom.Compiler.Code
...
System.InvalidOperationException:
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, CompilerParameters parameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, compilerParameters parameters, Assembly assembly, Hashtable assemblies)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.FromMappings(XmlMapping[] mappings, Type type)
at System.Web.Services.Protocols.SoapClientType..ctor(Type type)
at System.Web.Services.Protocols.SoapHttpClientProtocol..ctor()
at MAN.Applications.HFIF.Database.ClrExtensions.WebServiceSoapClient..ctor(String ...

How can I change the behaviour of my soap client class to use a particular XmlSerializer constructor that checks for pre-generated assemblies? Could you please give me a hint?

Thanks very much for your help. Frank

Sunday, February 12, 2012

Constant variables

Hi!
Is there a way to create constants (i.e. constant variables) in stored
procedures? Basically I'm looking for the T-SQL counterpart of Oracle
PL/SQL's
"x_var constant integer := 999;"-type declarations.
Thx,
AgostonHi!
I'm forwarding this because I couldn't find another way to avoid
multiposting once I have forgotten to cross-post to other groups. Sorry,
anyway.
"Agoston Bejo" <gusz1@.freemail.hu> wrote in message
news:ePy07CA6EHA.3472@.TK2MSFTNGP09.phx.gbl...
> Hi!
> Is there a way to create constants (i.e. constant variables) in stored
> procedures? Basically I'm looking for the T-SQL counterpart of Oracle
> PL/SQL's
> "x_var constant integer := 999;"-type declarations.
> Thx,
> Agoston
>|||No. TSQL Programming doesnt have any keyword for constant variable.
but if you want to store constants, it is recommended to keep them in
separate table and read it in the TSQL block. one level of security you can
provide is not to allow anyone to update the constants table.
In sql world, constants are data values. like string literals, numeric and
decimal values.
Av.
http://dotnetjunkies.com/WebLog/avnrao
http://www28.brinkster.com/avdotnet
"Agoston Bejo" <gusz1@.freemail.hu> wrote in message
news:#Y6k8PA6EHA.2572@.tk2msftngp13.phx.gbl...
> Hi!
> I'm forwarding this because I couldn't find another way to avoid
> multiposting once I have forgotten to cross-post to other groups. Sorry,
> anyway.
> "Agoston Bejo" <gusz1@.freemail.hu> wrote in message
> news:ePy07CA6EHA.3472@.TK2MSFTNGP09.phx.gbl...
> > Hi!
> > Is there a way to create constants (i.e. constant variables) in stored
> > procedures? Basically I'm looking for the T-SQL counterpart of Oracle
> > PL/SQL's
> > "x_var constant integer := 999;"-type declarations.
> >
> > Thx,
> > Agoston
> >
> >
>